diff --git a/ci-scripts/Jenkinsfile-GitLab-Container b/ci-scripts/Jenkinsfile-GitLab-Container index c22e6fabec717bc8f889846ee04c4cc3bcee9916..b37c9d4f4b30e08177ae58f6e5f497486b605b2b 100644 --- a/ci-scripts/Jenkinsfile-GitLab-Container +++ b/ci-scripts/Jenkinsfile-GitLab-Container @@ -278,6 +278,26 @@ pipeline { } } } + stage ("SA B200 Sanity Check") { + when { expression {doMandatoryTests} } + steps { + script { + triggerSlaveJob ('RAN-SA-B200-Module-SABOX-Container', 'Test-SA-B200') + } + } + post { + always { + script { + finalizeSlaveJob('RAN-SA-B200-Module-SABOX-Container') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } stage ("Test OAI NR UE - OAI gNB - TDD - Band 78 - N300") { when { expression {doMandatoryTests} } steps { diff --git a/ci-scripts/Jenkinsfile-push-registry b/ci-scripts/Jenkinsfile-push-registry index bc1a80ba614fc3554e4c9c1d00bd508acd06d551..feb1807c9122fd96565a63e9ab60ebd157086d66 100644 --- a/ci-scripts/Jenkinsfile-push-registry +++ b/ci-scripts/Jenkinsfile-push-registry @@ -66,7 +66,7 @@ pipeline { withCredentials([ [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.DH_Credentials}", usernameVariable: 'DH_Username', passwordVariable: 'DH_Password'] ]) { - def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue"] + def listOfImages = ["oai-enb", "oai-gnb", "oai-lte-ue", "oai-nr-ue", "proxy"] sh "docker login -u ${DH_Username} -p ${DH_Password} > /dev/null 2>&1" listOfImages.eachWithIndex { item, iindex -> sh "docker image tag ${item}:develop ${DH_Account}/${item}:develop" diff --git a/ci-scripts/Jenkinsfile-tmp-multi-enb b/ci-scripts/Jenkinsfile-tmp-multi-enb index c3b825ec0622c0faed979706840eb15a9a3a3687..fb523169201794ead2598b7911999913c7665421 100644 --- a/ci-scripts/Jenkinsfile-tmp-multi-enb +++ b/ci-scripts/Jenkinsfile-tmp-multi-enb @@ -36,6 +36,9 @@ def testStageName = params.pipelineTestStageName // Name of the phone resource def ciSmartPhoneResource = params.smartphonesResource +// Name of the phone resource +def ciEpcResource = params.epcResource + // Global Parameters. Normally they should be populated when the master job // triggers the slave job with parameters def eNB_Repository @@ -51,7 +54,7 @@ pipeline { options { disableConcurrentBuilds() ansiColor('xterm') - lock (ciSmartPhoneResource) + lock(extra: [[resource: ciEpcResource]], resource: ciSmartPhoneResource) } stages { stage ("Verify Parameters") { @@ -216,6 +219,76 @@ pipeline { } } } + stage ("Terminate") { + parallel { + stage('Terminate UE') { + // Bypassing this stage if there are no abd server defined + when { + expression { params.ADB_IPAddress != "none" } + } + steps { + echo '\u2705 \u001B[32mTerminate UE\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateUE --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password}" + } + } + } + stage('Terminate eNB') { + steps { + echo '\u2705 \u001B[32mTerminate eNB\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateeNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" + } + } + } + stage('Terminate SPGW') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + echo '\u2705 \u001B[32mTerminate SPGW\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}" + } + } + } + stage('Terminate MME') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + echo '\u2705 \u001B[32mTerminate MME\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}" + } + } + } + stage('Terminate HSS') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + echo '\u2705 \u001B[32mTerminate HSS\u001B[0m' + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + sh "python3 ci-scripts/main.py --mode=TerminateHSS --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCType=${params.EPC_Type} --EPCSourceCodePath=${params.EPC_SourceCodePath}" + } + } + } + } + } stage('Log Collection') { parallel { stage('Log Collection (eNB - Build)') { @@ -242,7 +315,7 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'] ]) { echo '\u2705 \u001B[32mLog Collection (eNB - Run)\u001B[0m' - sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath}" + sh "python3 ci-scripts/main.py --mode=LogCollecteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --BuildId=${env.BUILD_ID}" echo '\u2705 \u001B[32mLog Transfer (eNB - Run)\u001B[0m' sh "sshpass -p \'${eNB_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${eNB_Username}@${params.eNB_IPAddress}:${eNB_SourceCodePath}/cmake_targets/enb.log.zip ./enb.log.${env.BUILD_ID}.zip || true" @@ -259,6 +332,116 @@ pipeline { } } } + stage('Log Collection (SPGW)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (SPGW)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectSPGW --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (SPGW)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/spgw.log.zip ./spgw.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("spgw.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "spgw.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (MME)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (MME)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectMME --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (MME)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/mme.log.zip ./mme.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("mme.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "mme.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (HSS)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (HSS)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectHSS --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (HSS)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/hss.log.zip ./hss.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("hss.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "hss.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (Ping)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (Ping)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectPing --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (Ping)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/ping.log.zip ./ping.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("ping.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "ping.log.${env.BUILD_ID}.zip" + } + } + } + } + stage('Log Collection (Iperf)') { + // Bypassing this stage if EPC server is not defined + when { + expression { params.EPC_IPAddress != "none" } + } + steps { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'] + ]) { + echo '\u2705 \u001B[32mLog Collection (Iperf)\u001B[0m' + sh "python3 ci-scripts/main.py --mode=LogCollectIperf --EPCIPAddress=${params.EPC_IPAddress} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --EPCType=${params.EPC_Type}" + + echo '\u2705 \u001B[32mLog Transfer (Iperf)\u001B[0m' + sh "sshpass -p \'${EPC_Password}\' scp -o 'StrictHostKeyChecking no' -o 'ConnectTimeout 10' ${EPC_Username}@${params.EPC_IPAddress}:${EPC_SourceCodePath}/scripts/iperf.log.zip ./iperf.log.${env.BUILD_ID}.zip || true" + } + script { + if(fileExists("iperf.log.${env.BUILD_ID}.zip")) { + archiveArtifacts "iperf.log.${env.BUILD_ID}.zip" + } + } + } + } } } } diff --git a/ci-scripts/Jenkinsfile-trig-nsa b/ci-scripts/Jenkinsfile-trig-nsa index 3616b2c4042517a2f9d9964dee5972bbc26744b4..8e81b75e58e33ab2bf2963522371d86792b4332e 100644 --- a/ci-scripts/Jenkinsfile-trig-nsa +++ b/ci-scripts/Jenkinsfile-trig-nsa @@ -20,6 +20,9 @@ * contact@openairinterface.org */ +// necessary for reading JSON +import groovy.json.JsonSlurper + // Template Jenkins Declarative Pipeline script to run Test w/ RF HW // Location of the python executor node shall be in the same subnet as the others servers @@ -37,12 +40,12 @@ pipeline { stages { stage ("Launcher") { steps { - script { - //retrieve MR that are opened nd with tag NSA - MR_LIST= sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=NSA" | jq ".[].iid" || true ' - echo "List of selected MR:\n${MR_LIST}" - def MR_ARRAY = MR_LIST.split('\n') - //for every selected MR, retrieve the branch name and the latest commit + script { + // retrieve MR that are opened nd with tag NSA + MR_LIST = sh returnStdout: true, script: 'curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests?state=opened&per_page=100&labels=NSA" | jq -cj "[.[].iid]"' + echo "List of selected MRs: ${MR_LIST.trim()}" + def MR_ARRAY = new JsonSlurper().parseText(MR_LIST.trim()) + // for every selected MR, retrieve the branch name and the latest commit for (MR in MR_ARRAY) { SRC_BRANCH=sh returnStdout: true, script: """curl --silent "https://gitlab.eurecom.fr/api/v4/projects/oai%2Fopenairinterface5g/merge_requests/${MR}" | jq ".source_branch" || true """ SRC_BRANCH=SRC_BRANCH.trim() diff --git a/ci-scripts/ci_ueinfra.yaml b/ci-scripts/ci_ueinfra.yaml index 51fc4a264eb4794f7e325fa74b257a42c602e75c..76ebaf0f975ee69b25519a8ed134f24bcfc6c298 100644 --- a/ci-scripts/ci_ueinfra.yaml +++ b/ci-scripts/ci_ueinfra.yaml @@ -50,7 +50,7 @@ amarisoft_ue_1: WakeupScript : none DetachScript : none #end - Cmd : /root/NV17-12-21/ue/lteue + Cmd : /root/NV18-06-2022/ue/lteue Config : /root/NV17-12-21/ue/config/oaicicd-ue-Ping-SATest.cfg Duration : 60 Ping : /tmp/test_ue1.log @@ -71,7 +71,7 @@ amarisoft_ue_2: WakeupScript : none DetachScript : none #end - Cmd : /root/NV17-12-21/ue/lteue + Cmd : /root/NV18-06-2022/ue/lteue Config : /root/NV17-12-21/ue/config/xxxxxxx.cfg #to be updated for an other scenario Duration : 60 Ping : diff --git a/ci-scripts/cls_containerize.py b/ci-scripts/cls_containerize.py index 259db7bffe61f1789a20161eeb4d6ce73ac6bc60..8f992689e207ece7bec91aa328a32e6d448d37f1 100644 --- a/ci-scripts/cls_containerize.py +++ b/ci-scripts/cls_containerize.py @@ -74,6 +74,7 @@ class Containerize(): self.eNB2SourceCodePath = '' self.forcedWorkspaceCleanup = False self.imageKind = '' + self.proxyCommit = None self.eNB_instance = 0 self.eNB_serverId = ['', '', ''] self.yamlPath = ['', '', ''] @@ -421,6 +422,124 @@ class Containerize(): HTML.CreateHtmlTabFooter(False) sys.exit(1) + def BuildProxy(self, HTML): + if self.ranRepository == '' or self.ranBranch == '' or self.ranCommitID == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + if self.eNB_serverId[self.eNB_instance] == '0': + lIpAddr = self.eNBIPAddress + lUserName = self.eNBUserName + lPassWord = self.eNBPassword + lSourcePath = self.eNBSourceCodePath + elif self.eNB_serverId[self.eNB_instance] == '1': + lIpAddr = self.eNB1IPAddress + lUserName = self.eNB1UserName + lPassWord = self.eNB1Password + lSourcePath = self.eNB1SourceCodePath + elif self.eNB_serverId[self.eNB_instance] == '2': + lIpAddr = self.eNB2IPAddress + lUserName = self.eNB2UserName + lPassWord = self.eNB2Password + lSourcePath = self.eNB2SourceCodePath + if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter') + if self.proxyCommit is None: + HELP.GenericHelp(CONST.Version) + sys.exit('Insufficient Parameter (need proxyCommit for proxy build)') + logging.debug('Building on server: ' + lIpAddr) + mySSH = SSH.SSHConnection() + mySSH.open(lIpAddr, lUserName, lPassWord) + + # Check that we are on Ubuntu + mySSH.command('hostnamectl', '\$', 5) + result = re.search('Ubuntu', mySSH.getBefore()) + self.host = result.group(0) + if self.host != 'Ubuntu': + logging.error('\u001B[1m Can build proxy only on Ubuntu server\u001B[0m') + mySSH.close() + sys.exit(1) + + self.cli = 'docker' + self.cliBuildOptions = '--no-cache' + + # Workaround for some servers, we need to erase completely the workspace + if self.forcedWorkspaceCleanup: + mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15) + + oldRanCommidID = self.ranCommitID + oldRanRepository = self.ranRepository + oldRanAllowMerge = self.ranAllowMerge + self.ranCommitID = self.proxyCommit + self.ranRepository = 'https://github.com/EpiSci/oai-lte-5g-multi-ue-proxy.git' + self.ranAllowMerge = False + self._createWorkspace(mySSH, lPassWord, lSourcePath) + # to prevent accidentally overwriting data that might be used later + self.ranCommitID = oldRanCommidID + self.ranRepository = oldRanRepository + self.ranAllowMerge = oldRanAllowMerge + + # Let's remove any previous run artifacts if still there + mySSH.command(self.cli + ' image prune --force', '\$', 30) + # Remove any previous proxy image + mySSH.command(self.cli + ' image rm oai-lte-multi-ue-proxy:latest || true', '\$', 30) + + tag = self.proxyCommit + logging.debug('building L2sim proxy image for tag ' + tag) + # check if the corresponding proxy image with tag exists. If not, build it + mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' proxy:' + tag, '\$', 5) + buildProxy = mySSH.getBefore().count('o such image') != 0 + if buildProxy: + mySSH.command(self.cli + ' build ' + self.cliBuildOptions + ' --target oai-lte-multi-ue-proxy --tag proxy:' + tag + ' --file docker/Dockerfile.ubuntu18.04 . > cmake_targets/log/proxy-build.log 2>&1', '\$', 180) + # Note: at this point, OAI images are flattened, but we cannot do this + # here, as the flatten script is not in the proxy repo + mySSH.command(self.cli + ' image inspect --format=\'Size = {{.Size}} bytes\' proxy:' + tag, '\$', 5) + if mySSH.getBefore().count('o such image') != 0: + logging.error('\u001B[1m Build of L2sim proxy failed\u001B[0m') + mySSH.close() + HTML.CreateHtmlTestRow('commit ' + tag, 'KO', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTabFooter(False) + sys.exit(1) + else: + logging.debug('L2sim proxy image for tag ' + tag + ' already exists, skipping build') + + # retag the build images to that we pick it up later + mySSH.command('docker image tag proxy:' + tag + ' oai-lte-multi-ue-proxy:latest', '\$', 5) + + # no merge: is a push to develop, tag the image so we can push it to the registry + if not self.ranAllowMerge: + mySSH.command('docker image tag proxy:' + tag + ' proxy:develop', '\$', 5) + + # we assume that the host on which this is built will also run the proxy. The proxy + # currently requires the following command, and the docker-compose up mechanism of + # the CI does not allow to run arbitrary commands. Note that the following actually + # belongs to the deployment, not the build of the proxy... + logging.warning('the following command belongs to deployment, but no mechanism exists to exec it there!') + mySSH.command('sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up', '\$', 5) + + # Analyzing the logs + if buildProxy: + self.testCase_id = HTML.testCase_id + mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) + mySSH.command('mkdir -p proxy_build_log_' + self.testCase_id, '\$', 5) + mySSH.command('mv log/* ' + 'proxy_build_log_' + self.testCase_id, '\$', 5) + if (os.path.isfile('./proxy_build_log_' + self.testCase_id + '.zip')): + os.remove('./proxy_build_log_' + self.testCase_id + '.zip') + if (os.path.isdir('./proxy_build_log_' + self.testCase_id)): + shutil.rmtree('./proxy_build_log_' + self.testCase_id) + mySSH.command('zip -r -qq proxy_build_log_' + self.testCase_id + '.zip proxy_build_log_' + self.testCase_id, '\$', 5) + mySSH.copyin(lIpAddr, lUserName, lPassWord, lSourcePath + '/cmake_targets/build_log_' + self.testCase_id + '.zip', '.') + # don't delete such that we might recover the zips + #mySSH.command('rm -f build_log_' + self.testCase_id + '.zip','\$', 5) + + # Cleaning any created tmp volume + mySSH.command(self.cli + ' volume prune --force || true','\$', 15) + mySSH.close() + + logging.info('\u001B[1m Building L2sim Proxy Image Pass\u001B[0m') + HTML.CreateHtmlTestRow('commit ' + tag, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlNextTabHeaderTestRow(self.collectInfo, self.allImagesSize) + def Copy_Image_to_Test_Server(self, HTML): imageTag = 'develop' if (self.ranAllowMerge): @@ -567,8 +686,10 @@ class Containerize(): if status: HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) else: + self.exitStatus = 1 HTML.CreateHtmlTestRow('N/A', 'KO', CONST.ALL_PROCESSES_OK) + def UndeployObject(self, HTML, RAN): if self.eNB_serverId[self.eNB_instance] == '0': lIpAddr = self.eNBIPAddress @@ -588,7 +709,7 @@ class Containerize(): if lIpAddr == '' or lUserName == '' or lPassWord == '' or lSourcePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - logging.debug('\u001B[1m Deploying OAI Object on server: ' + lIpAddr + '\u001B[0m') + logging.debug('\u001B[1m Undeploying OAI Object from server: ' + lIpAddr + '\u001B[0m') mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) mySSH.command('cd ' + lSourcePath + '/' + self.yamlPath[self.eNB_instance], '\$', 5) diff --git a/ci-scripts/cls_oaicitest.py b/ci-scripts/cls_oaicitest.py index 9d5ae840387e4e9d12ba33352e913167fd1ce4c4..32d9c48966ce37d65beec7d1238eb0cb1d8a90c2 100644 --- a/ci-scripts/cls_oaicitest.py +++ b/ci-scripts/cls_oaicitest.py @@ -1329,7 +1329,7 @@ class OaiCiTest(): SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) if self.ADBCentralized: SSH.command('adb devices', '\$', 15) - self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore()) + self.UEDevices = re.findall('\r\n([A-Za-z0-9]+)\tdevice',SSH.getBefore()) #report number and id of devices found msg = "UEDevices found by GetAllUEDevices : " + " ".join(self.UEDevices) logging.debug(msg) @@ -1379,8 +1379,7 @@ class OaiCiTest(): SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) if self.ADBCentralized: SSH.command('lsusb | egrep --colour=never "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15) - #self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore()) - self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",SSH.getBefore()) + self.CatMDevices = re.findall('\r\n([A-Za-z0-9_]+)',SSH.getBefore()) else: if (os.path.isfile('./modules_list.txt')): os.remove('./modules_list.txt') @@ -2046,7 +2045,7 @@ class OaiCiTest(): req_bandwidth = '%.1f Gbits/sec' % req_bw req_bw = req_bw * 1000000000 - result = re.search('Server Report:\\\\r\\\\n(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', SSH.getBefore()) + result = re.search('Server Report:\r\n(?:|\[ *\d+\].*) (?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?P<jitter>[0-9\.]+ ms) +(\d+\/..\d+) +(\((?P<packetloss>[0-9\.]+)%\))', SSH.getBefore()) if result is not None: bitrate = result.group('bitrate') packetloss = result.group('packetloss') @@ -2262,7 +2261,7 @@ class OaiCiTest(): def Iperf_analyzeV3Output(self, lock, UE_IPAddress, device_id, statusQueue,SSH): - result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P<packetloss>[0-9\.]+)%\)) +(?:|receiver)\\\\r\\\\n(?:|\[ *\d+\] Sent \d+ datagrams)\\\\r\\\\niperf Done\.', SSH.getBefore()) + result = re.search('(?P<bitrate>[0-9\.]+ [KMG]bits\/sec) +(?:|[0-9\.]+ ms +\d+\/\d+ \((?P<packetloss>[0-9\.]+)%\)) +(?:|receiver)\r\n(?:|\[ *\d+\] Sent \d+ datagrams)\r\niperf Done\.', SSH.getBefore()) if result is None: result = re.search('(?P<error>iperf: error - [a-zA-Z0-9 :]+)', SSH.getBefore()) lock.acquire() @@ -3865,7 +3864,7 @@ class OaiCiTest(): SSH = sshconnection.SSHConnection() SSH.open(IPAddress, UserName, Password) SSH.command('lsb_release -a', '\$', 5) - result = re.search('Description:\\\\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore()) + result = re.search('Description:\t(?P<os_type>[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore()) if result is not None: OsVersion = result.group('os_type') logging.debug('OS is: ' + OsVersion) @@ -3883,13 +3882,13 @@ class OaiCiTest(): logging.debug('OS is: ' + OsVersion) HTML.OsVersion[idx]=OsVersion SSH.command('uname -r', '\$', 5) - result = re.search('uname -r\\\\r\\\\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', SSH.getBefore()) + result = re.search('uname -r\r\n(?P<kernel_version>[a-zA-Z0-9\-\_\.]+)', SSH.getBefore()) if result is not None: KernelVersion = result.group('kernel_version') logging.debug('Kernel Version is: ' + KernelVersion) HTML.KernelVersion[idx]=KernelVersion - SSH.command('dpkg --list | egrep --color=never libuhd003', '\$', 5) - result = re.search('libuhd003:amd64 *(?P<uhd_version>[0-9\.]+)', SSH.getBefore()) + SSH.command('dpkg --list | egrep --color=never libuhd', '\$', 5) + result = re.search('libuhd.*:amd64 *(?P<uhd_version>[0-9\.]+)', SSH.getBefore()) if result is not None: UhdVersion = result.group('uhd_version') logging.debug('UHD Version is: ' + UhdVersion) @@ -3902,7 +3901,7 @@ class OaiCiTest(): logging.debug('UHD Version is: ' + UhdVersion) HTML.UhdVersion[idx]=UhdVersion SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 180) - usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore()) + usrp_boards = re.findall('product: ([0-9A-Za-z]+)', SSH.getBefore()) count = 0 for board in usrp_boards: if count == 0: @@ -3914,14 +3913,18 @@ class OaiCiTest(): logging.debug('USRP Board(s) : ' + UsrpBoard) HTML.UsrpBoard[idx]=UsrpBoard SSH.command('lscpu', '\$', 5) - result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+).*Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', SSH.getBefore()) + result = re.search('CPU\(s\): *(?P<nb_cpus>[0-9]+)', SSH.getBefore()) if result is not None: CpuNb = result.group('nb_cpus') logging.debug('nb_cpus: ' + CpuNb) HTML.CpuNb[idx]=CpuNb + result = re.search('Model name: *(?P<model>[a-zA-Z0-9\-\_\.\ \(\)]+)', SSH.getBefore()) + if result is not None: CpuModel = result.group('model') logging.debug('model: ' + CpuModel) HTML.CpuModel[idx]=CpuModel + result = re.search('CPU MHz: *(?P<cpu_mhz>[0-9\.]+)', SSH.getBefore()) + if result is not None: CpuMHz = result.group('cpu_mhz') + ' MHz' logging.debug('cpu_mhz: ' + CpuMHz) HTML.CpuMHz[idx]=CpuMHz diff --git a/ci-scripts/conf_files/benetel-5g.conf b/ci-scripts/conf_files/benetel-5g.conf index 8f3b03fddc52948faeabdb00de9826daaeb21c96..3b872e56e96dfe18b7e7ee23c07fbef07985eb78 100644 --- a/ci-scripts/conf_files/benetel-5g.conf +++ b/ci-scripts/conf_files/benetel-5g.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf index 51ffb1d5cd2bb59f7818b390564b51278ec21ab7..a648db0efece1d80a10b665495cbee2453d2a5b9 100644 --- a/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/episci/episci_gnb.band78.sa.fr1.106PRB.usrpn310.conf @@ -32,7 +32,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( { diff --git a/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf b/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf index eac0b746336cdd9901d1ae5a73e862843c05048b..0db6ac9036b143ae162b2e573006b5778dbb2832 100644 --- a/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf +++ b/ci-scripts/conf_files/episci/episci_rcc.band78.tm1.106PRB.nfapi.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf index f80ce3751a93ed88e88c9fe95f1083c02052a454..84cb18d435f613576d80afd25b07e0c0939f0c90 100644 --- a/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/episci/proxy_gnb.band78.sa.fr1.106PRB.usrpn310.conf @@ -32,7 +32,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf b/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf index f61039ff17349fe8b7abca2109e6d491f1ab2e85..270ad7584578c938b41254d62a72abaedf7729dc 100644 --- a/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf +++ b/ci-scripts/conf_files/episci/proxy_rcc.band78.tm1.106PRB.nfapi.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gNB_SA_CU.conf b/ci-scripts/conf_files/gNB_SA_CU.conf index 9d64ae1976f9ab49720ba9aa338f97af2c69404a..f6d3e8575a7e2c58ea841a196f38fba733fb6678 100644 --- a/ci-scripts/conf_files/gNB_SA_CU.conf +++ b/ci-scripts/conf_files/gNB_SA_CU.conf @@ -44,7 +44,6 @@ gNBs = local_s_portd = 2152; remote_s_portc = 500; remote_s_portd = 2152; - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/ci-scripts/conf_files/gNB_SA_DU.conf b/ci-scripts/conf_files/gNB_SA_DU.conf index f95bdf91aee97e2c4c02f8b89db251622bacaf0c..4309c13dd395a172e589e66b4efc469e585fbf04 100644 --- a/ci-scripts/conf_files/gNB_SA_DU.conf +++ b/ci-scripts/conf_files/gNB_SA_DU.conf @@ -36,7 +36,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf index 04dc1b1373fbf7c843328f71d6d5efa928cb758a..49383072ed12e2fc36921bef6623b99c7dec415d 100644 --- a/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf +++ b/ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf @@ -37,7 +37,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; diff --git a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf index fd52c7fed5471b486f2d8d36aaea3b6332200eb6..610485fc9245fa2407a6ad79ce94474751f3a4c6 100644 --- a/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf +++ b/ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf @@ -38,7 +38,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; diff --git a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf index dcb3dd89b76fccd7eb91ca2b2d97f9d0c362377a..24ec8f17f8d1b7a92e80af13371ba90266bb3a68 100644 --- a/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band261.tm1.32PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf index 1019ec75ade5bb36558e7bb49bcfae9e0ffb6002..b3c7d7d1da5556e29143354918f0ed8647457627 100644 --- a/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band66.tm1.106PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf index 03155b85d8371f2e3e15ce8ae494e247097d1dbc..c668601c063d0b8ea870b2fc372fdbbf2d5985f0 100644 --- a/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.nsa_2x2.106PRB.usrpn310.conf @@ -19,7 +19,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; ul_prbblacklist = "51,52,53,54" diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf index 5e6b3fb217b52c512dc8e17e6ca6fb1acb81ec2f..92c3a7a2e985d00df2daa03ee6b8c035f699b76c 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.asue.conf @@ -41,7 +41,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pusch_AntennaPorts = 2; ul_prbblacklist = "51,52,53,54" do_SRS = 1; diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf index 09d9b503353d30ac51bdc951e5080889e2e6c038..672713d5042adafadefcbf583ef23fa264618ca7 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.2x2.usrpn310.conf @@ -37,7 +37,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; ul_prbblacklist = "51,52,53,54" diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf index 18ca7b5d1e8e31cf2f1abe3416b70a0a49bb5382..5bd8b26e054674aaa58eaa6138fd4708a4580028 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.ddsuu.2x2.usrpn310.conf @@ -37,7 +37,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pusch_AntennaPorts = 2; ul_prbblacklist = "51,52,53,54" do_SRS = 1; diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf index 9e1f499f0342d00c41a66786e6a2e3763f689c28..e1264bd069e5bc9b9699a842d616ae85897f1f9a 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.106PRB.usrpn310.conf @@ -37,7 +37,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; #pusch_TargetSNRx10 = 200; #pucch_TargetSNRx10 = 200; ul_prbblacklist = "51,52,53,54" diff --git a/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf index 42fc89b2eda29798754f49d84dc4cc1f50d80226..f92242138c7b41ae473654e4cbde273ae503b4ab 100644 --- a/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.sa.fr1.162PRB.2x2.usrpn310.conf @@ -37,7 +37,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 2; pusch_AntennaPorts = 2; #pusch_TargetSNRx10 = 200; diff --git a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf index 835e334bbb5fcc50c6af67ceae64e757d467dfc3..9334f2cf5918de0caae334c7bc07ebb0202f7718 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.106PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index f3515d388248d851fe8bbcffbf2bec39883e42ce..cd3ab6278e03d207e1426d11351ffe8c81c9f653 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -19,7 +19,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; servingCellConfigCommon = ( { diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf index 8f480d375717f5af5ea711ab5102bd93e9fbe080..371753eccc301bde31f96a1394ebb310c65d73c8 100644 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpn310.conf @@ -20,7 +20,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf b/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf index b78ca916f3c7983e8a3ee6ad06a9b5ca19152964..6b7122341de4bae2534cca057521a4f3e13f2911 100644 --- a/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf +++ b/ci-scripts/conf_files/gnb.sa.band66.fr1.106PRB.usrpn300.conf @@ -32,8 +32,8 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; + enable_sdap = 1; pdcch_ConfigSIB1 = ( { diff --git a/ci-scripts/conf_files/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.sa.band78.fr1.106PRB.usrpb210.conf new file mode 100644 index 0000000000000000000000000000000000000000..2a6053ab461fab1c726d38605212bc6983e66724 --- /dev/null +++ b/ci-scripts/conf_files/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -0,0 +1,344 @@ +Active_gNBs = ( "gNB-OAI"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + gNB_name = "gNB-OAI"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({ + mcc = 222; + mnc = 01; + mnc_length = 2; + snssaiList = ( + { + sst = 1; + #sd = 0x1; // 0 false, else true + } + ); + + }); + + nr_cellid = 12345678L; + + ////////// Physical parameters: + + min_rxtxtime = 2; + do_CSIRS = 1; + do_SRS = 1; + + pdcch_ConfigSIB1 = ( + { + controlResourceSetZero = 12; + searchSpaceZero = 0; + } + ); + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641280; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640008; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=27,L=48 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952 +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 28875; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -96; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = -25; + } + + ); + +# Dedicated Serving Cell Configuration +servingCellConfigDedicated = ({ + # BWP-Downlink + # BWP 1 Configuration + dl_bwp-Id_1 = 1; + dl_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_bwp1_subcarrierSpacing = 1; + + # BWP 2 Configuration + dl_bwp-Id_2 = 2; + dl_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_bwp2_subcarrierSpacing = 1; + + # BWP 3 Configuration + dl_bwp-Id_3 = 3; + dl_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_bwp3_subcarrierSpacing = 1; + + firstActiveDownlinkBWP-Id = 1; #BWP-Id + defaultDownlinkBWP-Id = 1; #BWP-Id + + # bwp-InactivityTimer ENUMERATED {ms2, ms3, ms4, ms5, ms6, ms8, ms10, ms20, ms30, + # ms40,ms50, ms60, ms80,ms100, ms200,ms300, ms500, + # ms750, ms1280, ms1920, ms2560, spare10, spare9, spare8, + # spare7, spare6, spare5, spare4, spare3, spare2, spare1 } + + # UplinkConfig + # BWP-Uplink + # BWP 1 Configuration + ul_bwp-Id_1 = 1; + ul_bwp1_locationAndBandwidth = 28875; // RBstart=0, L=106 (40 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_bwp1_subcarrierSpacing = 1; + + # BWP 2 Configuration + ul_bwp-Id_2 = 2; + ul_bwp2_locationAndBandwidth = 13750; // RBstart=0, L=51 (20 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_bwp2_subcarrierSpacing = 1; + + # BWP 3 Configuration + ul_bwp-Id_3 = 3; + ul_bwp3_locationAndBandwidth = 6325; // RBstart=0, L=24 (10 MHz BW) + # subcarrierSpacing + # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_bwp3_subcarrierSpacing = 1; + + firstActiveUplinkBWP-Id = 1; #BWP-Id + } +); + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// AMF parameters: + amf_ip_address = ( { ipv4 = "172.21.16.136"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + + NETWORK_INTERFACES : + { + GNB_INTERFACE_NAME_FOR_NG_AMF = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NG_AMF = "172.21.16.137/24"; + GNB_INTERFACE_NAME_FOR_NGU = "demo-oai"; + GNB_IPV4_ADDRESS_FOR_NGU = "172.21.16.137/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + }; + + } +); + +MACRLCs = ( +{ + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + pusch_TargetSNRx10 = 200; + pucch_TargetSNRx10 = 200; + ulsch_max_frame_inactivity = 0; +} +); + +L1s = ( +{ + num_cc = 1; + tr_n_preference = "local_mac"; + prach_dtx_threshold = 120; + pucch0_dtx_threshold = 100; + ofdm_offset_divisor = 8; #set this to UINT_MAX for offset 0 +} +); + +RUs = ( +{ + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 10; + att_rx = 10; + bands = [78]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + clock_src = "internal"; +} +); + +THREAD_STRUCT = ( +{ + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; +} +); + +rfsimulator : +{ + serveraddr = "server"; + serverport = "4043"; + options = (); #("saviq"); or/and "chanmod" + modelname = "AWGN"; + IQfile = "/tmp/rfsimulator.iqs"; +}; + +security = { + # preferred ciphering algorithms + # the first one of the list that an UE supports in chosen + # valid values: nea0, nea1, nea2, nea3 + ciphering_algorithms = ( "nea0" ); + + # preferred integrity algorithms + # the first one of the list that an UE supports in chosen + # valid values: nia0, nia1, nia2, nia3 + integrity_algorithms = ( "nia2", "nia0" ); + + # setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter + # what 'ciphering_algorithms' configures; same thing for 'drb_integrity' + drb_ciphering = "yes"; + drb_integrity = "no"; +}; + +log_config : +{ + global_log_level ="info"; + hw_log_level ="info"; + phy_log_level ="info"; + mac_log_level ="info"; + rlc_log_level ="info"; + pdcp_log_level ="info"; + rrc_log_level ="info"; + ngap_log_level ="debug"; + f1ap_log_level ="debug"; +}; + diff --git a/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf index bd3076a014cc9d75098288ca4c0cca05cb8b0d29..ad1471339a249a39b5308b122f7b864a7b4db5c3 100644 --- a/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.sa.band78.fr1.24PRB.usrpb210.conf @@ -32,9 +32,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 1; - pusch_AntennaPorts = 1; sib1_tda = 15; min_rxtxtime = 6; diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py index 0e0afefaaf7114d421bde4b02f0a2ff31727e1d3..9113d29ac9b6b6e367ebf15327c600117b2ddd8e 100644 --- a/ci-scripts/epc.py +++ b/ci-scripts/epc.py @@ -311,6 +311,8 @@ class EPCManagement(): tmp = str(response[0],'utf-8') self.MmeIPAddress = tmp.rstrip() logging.debug('AMF IP Address ' + self.MmeIPAddress) + else: + logging.error('no container with name oai-amf found, could not retrieve AMF IP address') mySSH.close() def CheckHSSProcess(self, status_queue): diff --git a/ci-scripts/main.py b/ci-scripts/main.py index adef8859423514c45d7b110b4ea2430376b43e5d..baed6a6011981f13d8f1885c78065836cb8967f1 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -102,7 +102,7 @@ def AssignParams(params_dict): def GetParametersFromXML(action): - if action == 'Build_eNB' or action == 'Build_Image': + if action == 'Build_eNB' or action == 'Build_Image' or action == 'Build_Proxy': RAN.Build_eNB_args=test.findtext('Build_eNB_args') CONTAINERS.imageKind=test.findtext('kind') forced_workspace_cleanup = test.findtext('forced_workspace_cleanup') @@ -138,6 +138,9 @@ def GetParametersFromXML(action): RAN.backgroundBuild=True else: RAN.backgroundBuild=False + proxy_commit = test.findtext('proxy_commit') + if proxy_commit is not None: + CONTAINERS.proxyCommit = proxy_commit elif action == 'WaitEndBuild_eNB': RAN.Build_eNB_args=test.findtext('Build_eNB_args') @@ -915,10 +918,14 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re HTML=ldpc.Run_PhySim(HTML,CONST,id) elif action == 'Build_Image': CONTAINERS.BuildImage(HTML) + elif action == 'Build_Proxy': + CONTAINERS.BuildProxy(HTML) elif action == 'Copy_Image_to_Test': CONTAINERS.Copy_Image_to_Test_Server(HTML) elif action == 'Deploy_Object': CONTAINERS.DeployObject(HTML, EPC) + if CONTAINERS.exitStatus==1: + RAN.prematureExit = True elif action == 'Undeploy_Object': CONTAINERS.UndeployObject(HTML, RAN) elif action == 'Cppcheck_Analysis': diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 680763d247dbac6a152913c13c3379f8eef66bda..a576054370da38ab8906a046425604e9a64b587c 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -374,7 +374,7 @@ class RANManagement(): mySSH.open(lIpAddr, lUserName, lPassWord) eth_interface = 'any' fltr = 'sctp' - logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m') + logging.debug('\u001B[1m Launching tshark on xNB on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m') pcapfile = pcapfile_prefix + self.testCase_id + '_log.pcap' mySSH.command('echo ' + lPassWord + ' | sudo -S rm -f /tmp/' + pcapfile , '\$', 5) mySSH.command('echo $USER; nohup sudo -E tshark -i ' + eth_interface + ' -f "' + fltr + '" -w /tmp/' + pcapfile + ' > /dev/null 2>&1 &','\$', 5) @@ -390,7 +390,7 @@ class RANManagement(): mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) eth_interface = 'any' fltr = 'sctp' - logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m') + logging.debug('\u001B[1m Launching tshark on EPC on interface ' + eth_interface + ' with filter "' + fltr + '"\u001B[0m') self.epcPcapFile = 'enb_' + self.testCase_id + '_s1log.pcap' mySSH.command('echo ' + localEpcPassword + ' | sudo -S rm -f /tmp/' + self.epcPcapFile , '\$', 5) mySSH.command('echo $USER; nohup sudo tshark -f "host ' + lIpAddr +'" -i ' + eth_interface + ' -f "' + fltr + '" -w /tmp/' + self.epcPcapFile + ' > /tmp/tshark.log 2>&1 &', localEpcUserName, 5) @@ -517,7 +517,7 @@ class RANManagement(): localEpcUserName = EPC.UserName localEpcPassword = EPC.Password mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') + logging.debug('\u001B[1m Stopping tshark on EPC \u001B[0m') mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) if self.epcPcapFile != '': mySSH.command('echo ' + localEpcPassword + ' | sudo -S chmod 666 /tmp/' + self.epcPcapFile, '\$', 5) @@ -644,18 +644,16 @@ class RANManagement(): time.sleep(5) mySSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) #stopping tshark (valid if eNB and enabled in xml, will not harm otherwise) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') + logging.debug('\u001B[1m Stopping tshark on xNB \u001B[0m') mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) time.sleep(1) mySSH.close() - # If tracer options is on, stopping tshark on EPC side - result = re.search('T_stdout', str(self.Initialize_eNB_args)) - if (result is not None): + if EPC.IPAddress != "none" and EPC.IPAddress != '': localEpcIpAddr = EPC.IPAddress localEpcUserName = EPC.UserName localEpcPassword = EPC.Password + logging.debug('\u001B[1m Stopping tshark on EPC (' + localEpcIpAddr + ') \u001B[0m') mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) - logging.debug('\u001B[1m Stopping tshark \u001B[0m') mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) time.sleep(1) if self.epcPcapFile != '': diff --git a/ci-scripts/sshconnection.py b/ci-scripts/sshconnection.py index dca3daa817ce8c1ab13cff291b29df605894092f..035da71426aa4a20b6d0bf5efc87fdbbdfacd229 100644 --- a/ci-scripts/sshconnection.py +++ b/ci-scripts/sshconnection.py @@ -60,7 +60,7 @@ class SSHConnection(): count = 0 connect_status = False while count < 4: - self.ssh = pexpect.spawn('ssh -o PubkeyAuthentication=no {}@{}'.format(username,ipaddress)) + self.ssh = pexpect.spawn('ssh -o PubkeyAuthentication=yes {}@{}'.format(username,ipaddress)) # Longer timeout at connection due to asterix slowness self.ssh.timeout = 25 self.sshresponse = self.ssh.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', 'Last login', pexpect.EOF, pexpect.TIMEOUT]) @@ -84,14 +84,11 @@ class SSHConnection(): else: logging.debug('self.sshresponse = ' + str(self.sshresponse)) elif self.sshresponse == 2: - # Checking if we are really on the remote client defined by its IP address - self.command('stdbuf -o0 ifconfig | egrep --color=never "inet addr:|inet "', prompt, 5) - result = re.search(str(ipaddress), str(self.ssh.before)) - if result is None: - self.close() - else: - count = 10 - connect_status = True + # We directly ended up on the remote server because of pubkey auth + count = 10 + connect_status = True + # this expect() seems to be necessary to advance the read buffer until the prompt, or getBefore() will not return the last command + self.sshresponse = self.ssh.expect([prompt]) else: # debug output logging.debug(str(self.ssh.before)) @@ -272,4 +269,4 @@ class SSHConnection(): sys.exit('SCP failed') def getBefore(self): - return str(self.ssh.before) + return self.ssh.before.decode('utf-8') diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml index b305aff42437b6797f9677155ad4b15adfbb1f9b..2c5f04b11fada246e667a2dcf74b5cd8b9c0dfb8 100755 --- a/ci-scripts/xml_class_list.yml +++ b/ci-scripts/xml_class_list.yml @@ -1,3 +1,4 @@ + - Build_Proxy - Build_PhySim - Run_PhySim - Build_eNB diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim.xml b/ci-scripts/xml_files/container_5g_f1_rfsim.xml index 05b20afed3a568c4a48d4292a91642f20f63ef29..61157f72dfeb98bb7ace14656c8e19c7672e8daf 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim.xml @@ -22,7 +22,7 @@ --> <testCaseList> <htmlTabRef>rfsim-5gnr-f1</htmlTabRef> - <htmlTabName>Testing 5G NR RF sim in containers - CU-DU F1 split</htmlTabName> + <htmlTabName>CU-DU F1 split</htmlTabName> <htmlTabIcon>wrench</htmlTabIcon> <TestCaseRequestedList> 100021 diff --git a/ci-scripts/xml_files/container_5g_f1_rfsim_down.xml b/ci-scripts/xml_files/container_5g_f1_rfsim_down.xml index ac3f7347bae311790ef413c98660ef4a446877eb..bb640381cf1e769c3514627fefcef809bd5a4cf9 100644 --- a/ci-scripts/xml_files/container_5g_f1_rfsim_down.xml +++ b/ci-scripts/xml_files/container_5g_f1_rfsim_down.xml @@ -22,7 +22,7 @@ --> <testCaseList> <htmlTabRef>rfsim-5gnr-down-f1</htmlTabRef> - <htmlTabName>CleanUp 5G RF - CU-DU F1 split</htmlTabName> + <htmlTabName>CleanUp CU-DU F1 split</htmlTabName> <htmlTabIcon>trash</htmlTabIcon> <TestCaseRequestedList> 100022 diff --git a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml index b41dafb767101369cd94473e92268901883fe657..9564b24b35d4cdf038d82df7d6347a508a0a4d9a 100644 --- a/ci-scripts/xml_files/container_5g_fdd_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_fdd_rfsim.xml @@ -22,7 +22,7 @@ --> <testCaseList> <htmlTabRef>rfsim-5gnr-fdd</htmlTabRef> - <htmlTabName>Testing 5G NR RF sim - Monolithic FDD gNB</htmlTabName> + <htmlTabName>Monolithic FDD gNB with SDAP</htmlTabName> <htmlTabIcon>wrench</htmlTabIcon> <repeatCount>4</repeatCount> <TestCaseRequestedList> diff --git a/ci-scripts/xml_files/container_5g_fdd_rfsim_down.xml b/ci-scripts/xml_files/container_5g_fdd_rfsim_down.xml index d960949f7d2a1befbfeb8f8381c7be8f3769f31f..12648ca750521b309138cd973a5f6988241738de 100644 --- a/ci-scripts/xml_files/container_5g_fdd_rfsim_down.xml +++ b/ci-scripts/xml_files/container_5g_fdd_rfsim_down.xml @@ -22,7 +22,7 @@ --> <testCaseList> <htmlTabRef>rfsim-5gnr-fdd-down</htmlTabRef> - <htmlTabName>CleanUp 5G RF - Monolithic FDD gNB</htmlTabName> + <htmlTabName>CleanUp Monolithic FDD gNB with SDAP</htmlTabName> <htmlTabIcon>trash</htmlTabIcon> <TestCaseRequestedList> 100012 diff --git a/ci-scripts/xml_files/container_5g_l2sim_proxy.xml b/ci-scripts/xml_files/container_5g_l2sim_proxy.xml new file mode 100644 index 0000000000000000000000000000000000000000..af1715d793669550b31871c5421620568aecb604 --- /dev/null +++ b/ci-scripts/xml_files/container_5g_l2sim_proxy.xml @@ -0,0 +1,42 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + + 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. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>l2sim-5gnr-proxy-build</htmlTabRef> + <htmlTabName>Build L2sim proxy image</htmlTabName> + <htmlTabIcon>wrench</htmlTabIcon> + <repeatCount>1</repeatCount> + <TestCaseRequestedList> + 000001 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="000001"> + <class>Build_Proxy</class> + <desc>Build L2sim Proxy Image</desc> + <eNB_instance>1</eNB_instance> + <eNB_serverId>1</eNB_serverId> + <forced_workspace_cleanup>True</forced_workspace_cleanup> + <proxy_commit>56cfdc0</proxy_commit> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/container_5g_rfsim.xml b/ci-scripts/xml_files/container_5g_rfsim.xml index a1f50948a501baa6e5fe316e335333a55b7f2ba0..653e1e65138d54d5f3c20750332b0ec5dd793658 100644 --- a/ci-scripts/xml_files/container_5g_rfsim.xml +++ b/ci-scripts/xml_files/container_5g_rfsim.xml @@ -22,7 +22,7 @@ --> <testCaseList> <htmlTabRef>rfsim-5gnr-tdd</htmlTabRef> - <htmlTabName>Testing 5G NR RF sim - Monolithic TDD gNB</htmlTabName> + <htmlTabName>Monolithic TDD gNB</htmlTabName> <htmlTabIcon>wrench</htmlTabIcon> <repeatCount>4</repeatCount> <TestCaseRequestedList> diff --git a/ci-scripts/xml_files/container_5g_rfsim_down.xml b/ci-scripts/xml_files/container_5g_rfsim_down.xml index b369b1fad8a96ab5457113695c3f56eaa719a5de..028ff6186498dd0418ead5a042a38d6ea2f22efe 100644 --- a/ci-scripts/xml_files/container_5g_rfsim_down.xml +++ b/ci-scripts/xml_files/container_5g_rfsim_down.xml @@ -22,7 +22,7 @@ --> <testCaseList> <htmlTabRef>rfsim-5gnr-down</htmlTabRef> - <htmlTabName>CleanUp 5G RF - Monolithic TDD gNB</htmlTabName> + <htmlTabName>CleanUp Monolithic TDD gNB</htmlTabName> <htmlTabIcon>trash</htmlTabIcon> <TestCaseRequestedList> 100002 diff --git a/ci-scripts/xml_files/container_nsa_b200_quectel.xml b/ci-scripts/xml_files/container_nsa_b200_quectel.xml index 8d04be3efd22d625fc21a701bb351b480f6dd0f4..51e6668cf00380e90550fd6c13c56c793f1fda19 100644 --- a/ci-scripts/xml_files/container_nsa_b200_quectel.xml +++ b/ci-scripts/xml_files/container_nsa_b200_quectel.xml @@ -53,7 +53,6 @@ <class>Initialize_UE</class> <desc>Initialize Quectel</desc> <id>idefix</id> - <UE_Trace>yes</UE_Trace> </testCase> diff --git a/ci-scripts/xml_files/container_sa_b200_quectel.xml b/ci-scripts/xml_files/container_sa_b200_quectel.xml new file mode 100644 index 0000000000000000000000000000000000000000..7f0475629ded37ee311645c830ed0d85d913c082 --- /dev/null +++ b/ci-scripts/xml_files/container_sa_b200_quectel.xml @@ -0,0 +1,168 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + + 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. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>TEST-SA-FR1-B200</htmlTabRef> + <htmlTabName>SA SanityCheck with QUECTEL</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <repeatCount>1</repeatCount> + <TestCaseRequestedList> + 010002 + 030000 + 030101 + 000001 + 010000 + 000001 + 050000 + 050001 + 010002 + 000001 + 030201 + </TestCaseRequestedList> + <!-- + 070001 + 070000 + 070002 + 050002 + 050003 + --> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="010000"> + <class>Initialize_UE</class> + <desc>Initialize Quectel</desc> + <id>idefix</id> + </testCase> + + + <testCase id="010002"> + <class>Terminate_UE</class> + <desc>Terminate Quectel</desc> + <id>idefix</id> + </testCase> + + <testCase id="030000"> + <class>Copy_Image_to_Test</class> + <desc>Copy gNB image to test server</desc> + <image_name>oai-gnb</image_name> + <registry_svr_id>1</registry_svr_id> + <test_svr_id>0</test_svr_id> + </testCase> + + <testCase id="030101"> + <class>Deploy_Object</class> + <desc>Deploy gNB (TDD/Band78/40MHz/B200) in a container</desc> + <yaml_path>ci-scripts/yaml_files/sa_b200_gnb</yaml_path> + <eNB_instance>0</eNB_instance> + <eNB_serverId>0</eNB_serverId> + </testCase> + + <testCase id="000001"> + <class>IdleSleep</class> + <desc>Sleep</desc> + <idle_sleep_time_in_sec>5</idle_sleep_time_in_sec> + </testCase> + + <testCase id="000002"> + <class>IdleSleep</class> + <desc>Sleep</desc> + <idle_sleep_time_in_sec>20</idle_sleep_time_in_sec> + </testCase> + + + <testCase id="050000"> + <class>Ping</class> + <desc>Ping: 20pings in 20sec</desc> + <id>idefix</id> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>1</ping_packetloss_threshold> + <ping_rttavg_threshold>15</ping_rttavg_threshold> + </testCase> + + <testCase id="050001"> + <class>Ping</class> + <desc>Ping: 100pings in 20sec</desc> + <id>idefix</id> + <ping_args>-c 100 -i 0.2</ping_args> + <ping_packetloss_threshold>1</ping_packetloss_threshold> + <ping_rttavg_threshold>15</ping_rttavg_threshold> + </testCase> + + <testCase id="050002"> + <class>Ping</class> + <desc>Ping: 20pings in 20sec</desc> + <id>idefix</id> + <ping_args>-c 20</ping_args> + <ping_packetloss_threshold>1</ping_packetloss_threshold> + <ping_rttavg_threshold>15</ping_rttavg_threshold> + </testCase> + + <testCase id="050003"> + <class>Ping</class> + <desc>Ping: 100pings in 20sec</desc> + <id>idefix</id> + <ping_args>-c 100 -i 0.2</ping_args> + <ping_packetloss_threshold>1</ping_packetloss_threshold> + <ping_rttavg_threshold>15</ping_rttavg_threshold> + </testCase> + + <testCase id="070000"> + <class>Iperf</class> + <desc>iperf (DL/125Mbps/UDP)(60 sec)(single-ue profile)</desc> + <iperf_args>-u -b 125M -t 60 -i 1 -fm</iperf_args> + <direction>DL</direction> + <id>idefix</id> + <iperf_packetloss_threshold>25</iperf_packetloss_threshold> + <iperf_bitrate_threshold>80</iperf_bitrate_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="070001"> + <class>Iperf</class> + <desc>iperf (UL/8Mbps/UDP)(60 sec)(single-ue profile)</desc> + <iperf_args>-u -b 8M -t 60 -i 1 -fm</iperf_args> + <direction>UL</direction> + <id>idefix</id> + <iperf_packetloss_threshold>1</iperf_packetloss_threshold> + <iperf_bitrate_threshold>95</iperf_bitrate_threshold> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="070002"> + <class>Iperf</class> + <desc>iperf (BIDIR TCP)(10 sec)(single-ue profile)</desc> + <iperf_args>-t 10 --bidir</iperf_args> + <direction>BIDIR</direction> + <id>idefix</id> + <iperf_profile>single-ue</iperf_profile> + </testCase> + + <testCase id="030201"> + <class>Undeploy_Object</class> + <desc>Undeploy gNB</desc> + <yaml_path>ci-scripts/yaml_files/sa_b200_gnb</yaml_path> + <eNB_instance>0</eNB_instance> + <eNB_serverId>0</eNB_serverId> + </testCase> + +</testCaseList> + diff --git a/ci-scripts/xml_files/container_sa_b200_terminate.xml b/ci-scripts/xml_files/container_sa_b200_terminate.xml new file mode 100644 index 0000000000000000000000000000000000000000..5a2b6bd4543d3183add1b67167f07fc37d2dd58e --- /dev/null +++ b/ci-scripts/xml_files/container_sa_b200_terminate.xml @@ -0,0 +1,42 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + + 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. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>TEST-SA-FR1-B200-terminate</htmlTabRef> + <htmlTabName>SA tear-down in case of problem</htmlTabName> + <htmlTabIcon>tasks</htmlTabIcon> + <repeatCount>1</repeatCount> + <TestCaseRequestedList> + 030201 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="030201"> + <class>Undeploy_Object</class> + <desc>Undeploy gNB</desc> + <yaml_path>ci-scripts/yaml_files/sa_b200_gnb</yaml_path> + <eNB_instance>1</eNB_instance> + <eNB_serverId>1</eNB_serverId> + <image_tag>sa-test</image_tag> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/fr1_5gc_closure.xml b/ci-scripts/xml_files/fr1_5gc_closure.xml new file mode 100644 index 0000000000000000000000000000000000000000..e5e57fa694bf75ac898cd8653c45c7ccab89cce6 --- /dev/null +++ b/ci-scripts/xml_files/fr1_5gc_closure.xml @@ -0,0 +1,37 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + + 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. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>5gc-closure</htmlTabRef> + <htmlTabName>5GC-Closure</htmlTabName> + <htmlTabIcon>log-out</htmlTabIcon> + <TestCaseRequestedList> +060000 + </TestCaseRequestedList> + <TestCaseExclusionList></TestCaseExclusionList> + + <testCase id="060000"> + <class>Terminate_5GCN</class> + <desc>Terminate 5GC</desc> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/fr1_5gc_start.xml b/ci-scripts/xml_files/fr1_5gc_start.xml new file mode 100644 index 0000000000000000000000000000000000000000..8758b761cd139c511ec8ce93dc00f72b6935eb19 --- /dev/null +++ b/ci-scripts/xml_files/fr1_5gc_start.xml @@ -0,0 +1,38 @@ +<!-- + + Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The OpenAirInterface Software Alliance licenses this file to You under + the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + + 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. + + For more information about the OpenAirInterface (OAI) Software Alliance: + contact@openairinterface.org + +--> +<testCaseList> + <htmlTabRef>5gc-start-tab</htmlTabRef> + <htmlTabName>5GC-Start</htmlTabName> + <htmlTabIcon>log-in</htmlTabIcon> + <TestCaseRequestedList> + 000100 + </TestCaseRequestedList> + <TestCaseExclusionList> + </TestCaseExclusionList> + + <testCase id="000100"> + <class>Initialize_5GCN</class> + <desc>Initialize 5GC</desc> + </testCase> + +</testCaseList> diff --git a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml index 2ef2b7d7ce74f2ac6f7b5a4bce433fd35effbb9b..459a16c323799ecfa11e4e88296083d520d8aaea 100644 --- a/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml +++ b/ci-scripts/xml_files/fr1_nsa_2x2_quectel.xml @@ -26,6 +26,7 @@ <htmlTabIcon>tasks</htmlTabIcon> <repeatCount>1</repeatCount> <TestCaseRequestedList> + 010002 030000 040000 000002 diff --git a/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml b/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml index 335fe873a163afc0002ee94c663efcc1973b5e0d..c8e0659330d594028e2da1377a1b64befb61ec6e 100644 --- a/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml +++ b/ci-scripts/xml_files/fr1_nsa_2x2_quectel_attach_detach.xml @@ -26,6 +26,7 @@ <htmlTabIcon>tasks</htmlTabIcon> <repeatCount>1</repeatCount> <TestCaseRequestedList> + 010002 031000 041000 000002 diff --git a/ci-scripts/xml_files/fr1_nsa_quectel.xml b/ci-scripts/xml_files/fr1_nsa_quectel.xml index a7fd0fc0d7c75a34d1cb05fdfbeac2845483446f..c72c61c0a2895c6cbf7bf800c7b19b4329835702 100644 --- a/ci-scripts/xml_files/fr1_nsa_quectel.xml +++ b/ci-scripts/xml_files/fr1_nsa_quectel.xml @@ -26,6 +26,7 @@ <htmlTabIcon>tasks</htmlTabIcon> <repeatCount>1</repeatCount> <TestCaseRequestedList> + 010002 030000 040000 000002 diff --git a/ci-scripts/xml_files/fr1_sa_quectel.xml b/ci-scripts/xml_files/fr1_sa_quectel.xml index 2b215479c24e69cefd4d833e08611b2939811d75..fd983d8835b15c63e1d64a1c2113e893334eb559 100644 --- a/ci-scripts/xml_files/fr1_sa_quectel.xml +++ b/ci-scripts/xml_files/fr1_sa_quectel.xml @@ -26,6 +26,7 @@ <htmlTabIcon>tasks</htmlTabIcon> <repeatCount>1</repeatCount> <TestCaseRequestedList> + 010002 040000 000002 010000 diff --git a/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml b/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml index 23eaccfcfd2d5fe6f9b4d82685b3b11e4e6b2459..f426bd6035416ac5aa7ae32feb663710d5b940db 100644 --- a/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml +++ b/ci-scripts/xml_files/fr1_sa_quectel_162prb.xml @@ -26,6 +26,7 @@ <htmlTabIcon>tasks</htmlTabIcon> <repeatCount>1</repeatCount> <TestCaseRequestedList> + 010002 042000 000002 010000 diff --git a/ci-scripts/xml_files/fr1_sa_quectel_stages.xml b/ci-scripts/xml_files/fr1_sa_quectel_stages.xml index 603f3f919b47f0de104a4a5d0b7db8f8d117c84b..48a9b60e7dbe6512245e1627ab952323c70965cb 100644 --- a/ci-scripts/xml_files/fr1_sa_quectel_stages.xml +++ b/ci-scripts/xml_files/fr1_sa_quectel_stages.xml @@ -26,6 +26,7 @@ <htmlTabIcon>tasks</htmlTabIcon> <repeatCount>1</repeatCount> <TestCaseRequestedList> + 011002 041000 000002 011000 diff --git a/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml b/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml index 0d18a52839b47278f383ae36329d8f627f0e448a..b6388eede258d65028faf81ee2dfecfc78195c32 100644 --- a/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml +++ b/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml @@ -26,6 +26,7 @@ <htmlTabIcon>tasks</htmlTabIcon> <repeatCount>1</repeatCount> <TestCaseRequestedList> + 010002 030000 000002 010000 diff --git a/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml b/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml index f84691ab488420f520969ed41cc695b0f19335ae..99c8f75e06f58aa58162f064769bbf0506359458 100644 --- a/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml +++ b/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml @@ -26,6 +26,7 @@ <htmlTabIcon>tasks</htmlTabIcon> <repeatCount>1</repeatCount> <TestCaseRequestedList> + 010002 030001 000002 010000 diff --git a/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml b/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..9ea52c12477a8436cd1a12cb991222a0321e950d --- /dev/null +++ b/ci-scripts/yaml_files/sa_b200_gnb/docker-compose.yml @@ -0,0 +1,44 @@ +version: '3.8' + +services: + gnb_mono_tdd: + image: oai-gnb:latest + privileged: true + container_name: sa-b200-gnb + environment: + USE_SA_TDD_MONO_B2XX: 'yes' + USE_B2XX: 'yes' + GNB_NAME: gNB-in-docker + MCC: '222' + MNC: '01' + MNC_LENGTH: 2 + TAC: 1 + NSSAI_SST: 1 + NSSAI_SD0: 1 + AMF_IP_ADDRESS: 172.21.16.136 + GNB_NGA_IF_NAME: eth0 + GNB_NGA_IP_ADDRESS: 192.168.68.194 + GNB_NGU_IF_NAME: eth0 + GNB_NGU_IP_ADDRESS: 192.168.68.194 + USE_ADDITIONAL_OPTIONS: --sa -E -q --RUs.[0].sdr_addrs serial=30C51D4 --continuous-tx --log_config.global_log_options level,nocolor,time,line_num,function + volumes: + - /dev:/dev + networks: + public_net: + ipv4_address: 192.168.68.194 + #entrypoint: /bin/bash -c "sleep infinity" + healthcheck: + # pgrep does NOT work + test: /bin/bash -c "ps aux | grep -v grep | grep -c softmodem" + interval: 10s + timeout: 5s + retries: 5 + +networks: + public_net: + name: sa-b200-gnb-net + ipam: + config: + - subnet: 192.168.68.192/26 + driver_opts: + com.docker.network.bridge.name: "sa-gnb-net" diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index c763c8950d4d4a4bbb998cf9a19f675e0f400bd2..429d14ff5492b25c6446132d8313f69318453f96 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -274,6 +274,12 @@ if (SANITIZE_ADDRESS) # wrong in the pthread library, or something subtly wrong in this CMakeLists.txt. Use Ubuntu 20.04 instead. endif () +add_boolean_option(SANITIZE_UNDEFINED False "enable the undefined behavior sanitizer (UBSan)") +if (SANITIZE_UNDEFINED) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all") +endif () + add_definitions("-DASN_DISABLE_OER_SUPPORT") ######################### @@ -331,13 +337,9 @@ add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"") # Debug related options ######################################### -add_boolean_option(ASN_EMIT_DEBUG False "ASN1 coder/decoder Debug") -add_boolean_option(ASN_THREAD_SAFE True "ASN1 coder/decoder Debug") -add_boolean_option(MSG_PRINT True "print debug messages") +add_boolean_option(DEBUG_ASN1C False "ASN1 coder/decoder Debug traces, see common/utils/config.h, the logs are regular OAI logs, in the log group 'ASN'") add_boolean_option(DISABLE_XER_PRINT False "print XER Format") add_boolean_option(XER_PRINT False "print XER Format") -add_boolean_option(RRC_MSG_PRINT False "print RRC messages") -add_boolean_option(PDCP_MSG_PRINT False "print PDCP messages to /tmp/pdcp.log") add_boolean_option(DEBUG_PDCP_PAYLOAD False "print PDCP PDU to stdout") # if true, make sure that global and PDCP log levels are trace add_boolean_option(DEBUG_MAC_INTERFACE False "print MAC-RLC PDU exchange to stdout") # if true, make sure that global and PDCP log levels are trace add_boolean_option(TRACE_RLC_PAYLOAD False "print RLC PDU to stdout") # if true, make sure that global and PDCP log levels are trace @@ -355,6 +357,12 @@ add_library(ITTI ) add_dependencies(ITTI rrc_flag) +# asn1c skeletons have hardcoded this flag to make customized debug logs +# OAI uses this feature to re-use OAI LOG_I(ASN, ...) +if (DEBUG_ASN1C) + add_definitions(-DHAVE_CONFIG_H) +endif() + ################################################## # ASN.1 grammar C code generation & dependencies # ################################################## @@ -864,7 +872,6 @@ add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION w add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION with max 256 UE") add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE") add_boolean_option(UESIM_EXPANSION False "enable UESIM_EXPANSION with max 256 UE") -add_boolean_option(ITTI_SIM False "enable itti simulator") ######################## # Include order @@ -1829,7 +1836,15 @@ set(NR_PDCP_SRC ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c ${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c + #hack: include these files to compile the nr phy simulators + #these files should not be here, will be removed at some point when the + #computation is done directly inside nr_pdcp_integrity_nia1.c instead + #of reusing code of osa_stream_eia.c + ${OPENAIR2_DIR}/UTIL/OSA/osa_stream_eia.c + ${OPENAIR2_DIR}/UTIL/OSA/osa_snow3g.c + ${OPENAIR2_DIR}/UTIL/OSA/osa_rijndael.c ) set(NR_SDAP_SRC @@ -1883,6 +1898,8 @@ set(L2_NR_SRC ${NR_RRC_DIR}/rrc_gNB.c ${NR_RRC_DIR}/nr_rrc_common.c ${NR_RRC_DIR}/L2_nr_interface.c + ${NR_RRC_DIR}/mac_rrc_dl_direct.c + ${NR_RRC_DIR}/mac_rrc_dl_f1ap.c ${NR_RRC_DIR}/nr_rrc_config.c ${NR_RRC_DIR}/rrc_gNB_nsa.c ${NR_RRC_DIR}/rrc_gNB_internode.c @@ -1961,6 +1978,9 @@ set (MAC_NR_SRC ${NR_GNB_MAC_DIR}/gNB_scheduler_uci.c ${NR_GNB_MAC_DIR}/gNB_scheduler_srs.c ${NR_GNB_MAC_DIR}/gNB_scheduler_RA.c + ${NR_GNB_MAC_DIR}/mac_rrc_dl_handler.c + ${NR_GNB_MAC_DIR}/mac_rrc_ul_direct.c + ${NR_GNB_MAC_DIR}/mac_rrc_ul_f1ap.c ) @@ -1977,6 +1997,7 @@ set (MAC_SRC_UE set (MAC_NR_SRC_UE ${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c + ${NR_UE_PHY_INTERFACE_DIR}/NR_Packet_Drop.c ${NR_UE_MAC_DIR}/config_ue.c ${NR_UE_MAC_DIR}/mac_vars.c ${NR_UE_MAC_DIR}/main_ue_nr.c @@ -3049,7 +3070,7 @@ if (${T_TRACER}) foreach(i #all "add_executable" definitions (except tests, rb_tool, updatefw) lte-softmodem lte-uesoftmodem nr-softmodem - nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 nr-ittisim + nr-uesoftmodem dlsim dlsim_tm4 dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim prachsim syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim nr_ulschsim ldpctest polartest smallblocktest cu_test du_test @@ -3135,50 +3156,6 @@ add_executable(rb_tool ) target_include_directories(rb_tool PRIVATE ${OPENAIR2_DIR}/NETWORK_DRIVER/MESH/) -# nr-ittisim -################################################### - -add_executable(nr-ittisim - ${rrc_h} - ${nr_rrc_h} - ${OPENAIR2_DIR}/GNB_APP/gnb_app.c - ${OPENAIR2_DIR}/GNB_APP/gnb_config.c - ${OPENAIR_DIR}/executables/nr-gnb.c - ${OPENAIR_DIR}/executables/nr-ru.c - ${OPENAIR2_DIR}/SIMULATION/NR_RRC/itti_sim.c - ${OPENAIR_DIR}/executables/softmodem-common.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c - ${OPENAIR2_DIR}/RRC/NAS/nas_config.c - ${OPENAIR2_DIR}/RRC/NAS/rb_config.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c - ${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${OPENAIR_DIR}/common/utils/lte/ue_power.c - ${OPENAIR_DIR}/common/utils/lte/prach_utils.c - ${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api_to_fix.c - ${XFORMSINTERFACE_SOURCE} - ${T_SOURCE} - ${SHLIB_LOADER_SOURCES} - ) - -target_link_libraries (nr-ittisim - -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU GTPV1U SECU_CN SECU_OSA - ITTI ${FLPT_MSG_LIB} ${FLEXRAN_AGENT_LIB} ${RAL_LIB} ${NAS_SIM_LIB} RRC_LIB NR_RRC_LIB - NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB - X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${FSPT_MSG_LIB} - PHY_NR_UE SCHED_NR_UE_LIB NR_L2_UE - -Wl,--end-group z dl) - -target_link_libraries (nr-ittisim ${LIBXML2_LIBRARIES}) -target_link_libraries (nr-ittisim pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) -target_link_libraries (nr-ittisim ${LIB_LMS_LIBRARIES}) -target_link_libraries (nr-ittisim ${T_LIB}) - -add_dependencies( nr-ittisim ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) - # ??? #################### list(APPEND oai_nw_drv_src device.c common.c ioctl.c classifier.c tool.c) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 61b5b8ba95a7fba479c6bee9caf781cfbfa6608c..88654ac9b54dc53054038be6f5336141396502f4 100755 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1062,7 +1062,8 @@ (Test3: PBCH-only, 217 PRB), (Test4: PBCH and synchronization, 217 RPB), (Test5: PBCH-only, 273 PRB), - (Test6: PBCH and synchronization, 273 PRB)</desc> + (Test6: PBCH and synchronization, 273 PRB), + (Test7: PBCH and synchronization, 106PBR, SSB SC OFFSET 6)</desc> <pre_compile_prog></pre_compile_prog> <compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog> <compile_prog_args> --phy_simulators -c </compile_prog_args> @@ -1074,8 +1075,9 @@ -s-11 -S-8 -n10 -R217 -s-11 -S-8 -n10 -o8000 -I -R217 -s-11 -S-8 -n10 -R273 - -s-11 -S-8 -n10 -o8000 -I -R273</main_exec_args> - <tags>nr_pbchsim.test1 nr_pbchsim.test2 nr_pbchsim.test3 nr_pbchsim.test4 nr_pbchsim.test5 nr_pbchsim.test6</tags> + -s-11 -S-8 -n10 -o8000 -I -R273 + -s-11 -S-8 -n10 -R106 -O6</main_exec_args> + <tags>nr_pbchsim.test1 nr_pbchsim.test2 nr_pbchsim.test3 nr_pbchsim.test4 nr_pbchsim.test5 nr_pbchsim.test6 nr_pbchsim.test7</tags> <search_expr_true>PBCH test OK</search_expr_true> <search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false> <nruns>3</nruns> diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 5a201fcfef934a1d7946bb5622c3cf2aab7bdfa2..09029c285a397c034f8defe9688ab191cd4c6ac0 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -171,10 +171,12 @@ Options: Skip build for shared libraries to reduce compilation time when building frequently for debugging purposes --ninja Tell cmake to use the Ninja build system. Without, will generate make files +--sanitize + Shortcut for usage of --sanitize-address --sanitize-undefined --sanitize-address | -fsanitize=address - Enable the address sanitizer on all targets ---ittiSIM - Makes the itti simulator + Enable the address sanitizer on all targets +--sanitize-undefined | -fsanitize=undefined + Enable the undefined behavior sanitizer on all targets -h | --help Print this help @@ -451,14 +453,15 @@ function main() { CMAKE_CMD="$CMAKE_CMD -GNinja" MAKE_CMD=ninja shift;; + --sanitize) + CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True -DSANITIZE_UNDEFINED=True" + shift;; --sanitize-address | -fsanitize=address) grep -sq "Ubuntu 18.04" /etc/os-release && echo_error "Bug in OS with this option, see CMakeLists.txt" CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True" shift;; - --ittiSIM) - ittiSIM=1 - CMAKE_CMD="$CMAKE_CMD -DITTI_SIM=True" - echo_info "Will compile itti simulator" + --sanitize-undefined | -fundefined=address) + CMAKE_CMD="$CMAKE_CMD -DSANITIZE_UNDEFINED=True" shift;; -h | --help) print_help @@ -613,9 +616,6 @@ function main() { if [ "$nrUE" = 1 ] ; then execlist="$execlist nr-uesoftmodem" fi - if [ "$ittiSIM" = "1" ] ; then - execlist="$execlist nr-ittisim" - fi if [[ "$execlist" == "" && "$SIMUS_PHY" != "1" ]]; then echo_success "installing dependencies successful" diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 179e2de42845ad295300a8d3aad73d7ff398db3c..d35f90fcce20a1f9c66e3470c013d1f0b65bcac8 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -109,6 +109,7 @@ check_supported_distribution() { "ubuntu18.04") return 0 ;; "ubuntu16.04") return 0 ;; "fedora35") return 0 ;; + "fedora36") return 0 ;; "rhel7") return 0 ;; "rhel7.6") return 0 ;; "rhel7.7") return 0 ;; @@ -196,8 +197,8 @@ check_warnings() { #argument: # $1: log file check_errors() { - #we look for 'warning:' in the compilation log file - error_count=`grep "error:" "$1" | wc -l` + #we look for 'error:' in the compilation log file + error_count=`grep -c "error:" "$1"` if [ $error_count -gt 0 ]; then echo_error "ERROR: $error_count error. See $1" fi @@ -623,7 +624,6 @@ check_install_additional_tools (){ android-tools-adb \ wvdial \ sshpass \ - nscd \ bc \ ntp" elif [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then @@ -648,7 +648,6 @@ check_install_additional_tools (){ wvdial \ numpy \ sshpass \ - nscd \ python2-paramiko \ python-pyroute2 \ python-netifaces \ @@ -676,7 +675,6 @@ check_install_additional_tools (){ wvdial \ python-numpy \ sshpass \ - nscd \ python-paramiko \ python-pyroute2 \ python-netifaces \ diff --git a/common/utils/collection/linear_alloc.h b/common/utils/collection/linear_alloc.h new file mode 100644 index 0000000000000000000000000000000000000000..ac8a305ff64614a9efeb474eb4d3c878d5d469ef --- /dev/null +++ b/common/utils/collection/linear_alloc.h @@ -0,0 +1,71 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef LINEAR_ALLOC_H +#define LINEAR_ALLOC_H + +#include <limits.h> + +typedef unsigned int uid_t; +#define UID_LINEAR_ALLOCATOR_SIZE 1024 +#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE (((UID_LINEAR_ALLOCATOR_SIZE/8)/sizeof(unsigned int)) + 1) +typedef struct uid_linear_allocator_s { + unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE]; +} uid_allocator_t; + +static inline void uid_linear_allocator_init(uid_allocator_t *uia) { + memset(uia, 0, sizeof(uid_allocator_t)); +} + +static inline uid_t uid_linear_allocator_new(uid_allocator_t *uia) { + unsigned int bit_index = 1; + uid_t uid = 0; + + for (unsigned int i = 0; i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE; i++) { + if (uia->bitmap[i] != UINT_MAX) { + bit_index = 1; + uid = 0; + + while ((uia->bitmap[i] & bit_index) == bit_index) { + bit_index = bit_index << 1; + uid += 1; + } + + uia->bitmap[i] |= bit_index; + return uid + (i*sizeof(unsigned int)*8); + } + } + + return UINT_MAX; +} + + +static inline void uid_linear_allocator_free(uid_allocator_t *uia, uid_t uid) { + const unsigned int i = uid/sizeof(unsigned int)/8; + const unsigned int bit = uid % (sizeof(unsigned int) * 8); + const unsigned int value = ~(1 << bit); + + if (i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE) { + uia->bitmap[i] &= value; + } +} + +#endif /* LINEAR_ALLOC_H */ diff --git a/common/utils/config.h b/common/utils/config.h new file mode 100644 index 0000000000000000000000000000000000000000..597ead7ed604ea1528af4b7d14665179333e875a --- /dev/null +++ b/common/utils/config.h @@ -0,0 +1,56 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef UTILS_CONFIG_H_ASN1 +#define UTILS_CONFIG_H_ASN1 + +// This is hard coded file name "config.h" and HAVE_CONFIG_H_ in asn1c skeletons + +/* + * This file "config.h" will be used by asn1c if HAVE_CONFIG_H_ is defined and + * included. This logs asn1c encoder and decoder traces at execution time using + * the regular OAI logging system, i.e., LOG_I(ASN...); + * + * As it is very verbose, note that you can change the log level per module in + * source or in gdb, e.g., to only activate it for a short time. + * + * In code: + * ``` + * set_log(ASN, OAI_INFO); // enable logging + * // do your encoding here + * set_log(ASN, OAI_ERR); // disable logging + * ``` + * + * in gdb: + * ``` + * gdb> p set_log(ASN, 1) // disable log, 1 == OAI_ERR + * gdb> p set_log(ASN, 5) // enable log, 5 == OAI_INFO + * ``` + */ + +#include "common/utils/LOG/log.h" +#if DEBUG_ASN1C +#define ASN_DEBUG(x...) do{ LOG_I(ASN,x);LOG_I(ASN,"\n"); } while(false) +#else +#define ASN_DEBUG(x...) +#endif + +#endif /* UTILS_CONFIG_H_ASN1 */ diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 6add03c324db9f3d6903cd341c425511f47f5500..0fb4824d42c8ecbf51c11470c3a75141d5cfef9b 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -472,6 +472,236 @@ int get_subband_size(int NPRB,int size) { } +void get_samplerate_and_bw(int mu, + int n_rb, + int8_t threequarter_fs, + double *sample_rate, + unsigned int *samples_per_frame, + double *tx_bw, + double *rx_bw) { + + if (mu == 0) { + switch(n_rb) { + case 270: + if (threequarter_fs) { + *sample_rate=92.16e6; + *samples_per_frame = 921600; + *tx_bw = 50e6; + *rx_bw = 50e6; + } else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 50e6; + *rx_bw = 50e6; + } + case 216: + if (threequarter_fs) { + *sample_rate=46.08e6; + *samples_per_frame = 460800; + *tx_bw = 40e6; + *rx_bw = 40e6; + } + else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 40e6; + *rx_bw = 40e6; + } + break; + case 160: //30 MHz + case 133: //25 MHz + if (threequarter_fs) { + AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",n_rb); + } + else { + *sample_rate=30.72e6; + *samples_per_frame = 307200; + *tx_bw = 20e6; + *rx_bw = 20e6; + } + case 106: + if (threequarter_fs) { + *sample_rate=23.04e6; + *samples_per_frame = 230400; + *tx_bw = 20e6; + *rx_bw = 20e6; + } + else { + *sample_rate=30.72e6; + *samples_per_frame = 307200; + *tx_bw = 20e6; + *rx_bw = 20e6; + } + break; + case 52: + if (threequarter_fs) { + *sample_rate=11.52e6; + *samples_per_frame = 115200; + *tx_bw = 10e6; + *rx_bw = 10e6; + } + else { + *sample_rate=15.36e6; + *samples_per_frame = 153600; + *tx_bw = 10e6; + *rx_bw = 10e6; + } + case 25: + if (threequarter_fs) { + *sample_rate=5.76e6; + *samples_per_frame = 57600; + *tx_bw = 5e6; + *rx_bw = 5e6; + } + else { + *sample_rate=7.68e6; + *samples_per_frame = 76800; + *tx_bw = 5e6; + *rx_bw = 5e6; + } + break; + default: + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",n_rb,mu); + } + } else if (mu == 1) { + switch(n_rb) { + + case 273: + if (threequarter_fs) { + *sample_rate=184.32e6; + *samples_per_frame = 1843200; + *tx_bw = 100e6; + *rx_bw = 100e6; + } else { + *sample_rate=122.88e6; + *samples_per_frame = 1228800; + *tx_bw = 100e6; + *rx_bw = 100e6; + } + break; + case 217: + if (threequarter_fs) { + *sample_rate=92.16e6; + *samples_per_frame = 921600; + *tx_bw = 80e6; + *rx_bw = 80e6; + } else { + *sample_rate=122.88e6; + *samples_per_frame = 1228800; + *tx_bw = 80e6; + *rx_bw = 80e6; + } + break; + case 162 : + if (threequarter_fs) { + AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",n_rb); + } + else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 60e6; + *rx_bw = 60e6; + } + + break; + + case 133 : + if (threequarter_fs) { + AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",n_rb); + } + else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 50e6; + *rx_bw = 50e6; + } + + break; + case 106: + if (threequarter_fs) { + *sample_rate=46.08e6; + *samples_per_frame = 460800; + *tx_bw = 40e6; + *rx_bw = 40e6; + } + else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 40e6; + *rx_bw = 40e6; + } + break; + case 51: + if (threequarter_fs) { + *sample_rate=23.04e6; + *samples_per_frame = 230400; + *tx_bw = 20e6; + *rx_bw = 20e6; + } + else { + *sample_rate=30.72e6; + *samples_per_frame = 307200; + *tx_bw = 20e6; + *rx_bw = 20e6; + } + break; + case 24: + if (threequarter_fs) { + *sample_rate=11.52e6; + *samples_per_frame = 115200; + *tx_bw = 10e6; + *rx_bw = 10e6; + } + else { + *sample_rate=15.36e6; + *samples_per_frame = 153600; + *tx_bw = 10e6; + *rx_bw = 10e6; + } + break; + default: + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",n_rb,mu); + } + } else if (mu == 3) { + switch(n_rb) { + case 66: + if (threequarter_fs) { + *sample_rate=184.32e6; + *samples_per_frame = 1843200; + *tx_bw = 100e6; + *rx_bw = 100e6; + } else { + *sample_rate = 122.88e6; + *samples_per_frame = 1228800; + *tx_bw = 100e6; + *rx_bw = 100e6; + } + + break; + + case 32: + if (threequarter_fs) { + *sample_rate=92.16e6; + *samples_per_frame = 921600; + *tx_bw = 50e6; + *rx_bw = 50e6; + } else { + *sample_rate=61.44e6; + *samples_per_frame = 614400; + *tx_bw = 50e6; + *rx_bw = 50e6; + } + + break; + + default: + AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",n_rb,mu); + } + } else { + AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); + } +} + // from start symbol index and nb or symbols to symbol occupation bitmap in a slot uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols) { return ((1<<nrOfSymbols)-1)<<startSymbolIndex; diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 5f7f670ce92938f058410d0f698f61e9fde2fa8e..4f474e28121bf4d5bac3c7e1fcb257209db086e1 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -76,6 +76,13 @@ uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols); int get_nb_periods_per_frame(uint8_t tdd_period); int get_supported_band_index(int scs, int band, int n_rbs); long rrc_get_max_nr_csrs(uint8_t max_rbs, long b_SRS); +void get_samplerate_and_bw(int mu, + int n_rb, + int8_t threequarter_fs, + double *sample_rate, + unsigned int *samples_per_frame, + double *tx_bw, + double *rx_bw); #define CEILIDIV(a,b) ((a+b-1)/b) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) diff --git a/common/utils/ocp_itti/all_msg.h b/common/utils/ocp_itti/all_msg.h index 8f7f48ed5a288737f9917bc0df73bbe9ae2653bd..c4bedc2cf62ea7d38bea5322f7a5ba2ff840519a 100644 --- a/common/utils/ocp_itti/all_msg.h +++ b/common/utils/ocp_itti/all_msg.h @@ -17,7 +17,4 @@ #include "openair2/COMMON/flexran_messages_def.h" #include "openair2/COMMON/f1ap_messages_def.h" #include "openair2/COMMON/ngap_messages_def.h" -#if ITTI_SIM -#include "openair2/COMMON/itti_sim_messages_def.h" -#endif diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index e595311b26cc90720653e39318127cd45c757ba0..3a03e380a1dabceab55e420042b65797a4ae7ef3 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -262,10 +262,6 @@ void *rrc_enb_process_itti_msg(void *); #include <openair3/SCTP/sctp_eNB_task.h> #include <openair3/NGAP/ngap_gNB.h> -#ifdef ITTI_SIM - #include <openair2/COMMON/itti_sim_messages_types.h> -#endif - /* static const char *const messages_definition_xml = { #include <messages_xml.h> @@ -308,9 +304,11 @@ void *rrc_enb_process_msg(void *); TASK_DEF(TASK_BM, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_PHY_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_MAC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_MAC_GNB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RLC_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_ENB_NB_IoT, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_PDCP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \ + TASK_DEF(TASK_PDCP_GNB, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_DATA_FORWARDING, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_END_MARKER, TASK_PRIORITY_MED, 200, NULL, NULL) \ TASK_DEF(TASK_RRC_ENB, TASK_PRIORITY_MED, 200, NULL,NULL)\ diff --git a/common/utils/time_meas.h b/common/utils/time_meas.h index fded7f1a9c9a3195535f8c5b279d0124c8ed1c1c..eb81d09434cefab1879c28aad1c286eaee15d45a 100644 --- a/common/utils/time_meas.h +++ b/common/utils/time_meas.h @@ -62,7 +62,7 @@ typedef struct time_stats { oai_cputime_t in; /*!< \brief time at measure starting point */ oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/ oai_cputime_t p_time; /*!< \brief absolute process duration */ - oai_cputime_t diff_square; /*!< \brief process duration square */ + double diff_square; /*!< \brief process duration square */ oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/ int trials; /*!< \brief number of start point - end point iterations */ int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */ @@ -156,7 +156,7 @@ static inline void stop_meas(time_stats_t *ts) { ts->diff += (out-ts->in); /// process duration is the difference between two clock points ts->p_time = (out-ts->in); - ts->diff_square += (out-ts->in)*(out-ts->in); + ts->diff_square += ((double)out-ts->in)*((double)out-ts->in); if ((out-ts->in) > ts->max) ts->max = out-ts->in; diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index d0856b415d3761ad639c377ec816ea18fd9fa445..5db6e44d8d2f788375f05649f033a0de2d95be02 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -440,6 +440,10 @@ The following features are valid for the gNB and the 5G-NR UE. - PTRS support - Support for 1, 2 and 4 RX antennas - Support for up to 2 layers (currently limited to DMRS configuration type 2) +* Measurements based on NR-CSIRS + - RI, PMI and CQI computation + - Support for 1 and 2 RX antennas + - Support for up to 2 layers * NR-PUSCH (including Segmentation, LDPC encoding, rate matching, scrambling, modulation, RB mapping, etc). - PUSCH mapping type A and B - DMRS configuration type 1 and 2 @@ -488,12 +492,15 @@ The following features are valid for the gNB and the 5G-NR UE. * UCI processing - ACK/NACK processing - Triggering periodic SR - - CSI measurement reporting (SSB RSRP only) -* DLSH scheduler + - CSI measurement reporting +* DLSCH scheduler - Configuration of fapi PDU according to DCI - HARQ procedures * ULSCH scheduler - Configuration of fapi PDU according to DCI +* NR-CSIRS scheduler + - Scheduling of NR-CSIRS reception + - Fill UCI for CSI measurement reporting * Scheduler procedures for SRS transmission - Periodic SRS transmission * Bandwidth part (BWP) operation diff --git a/doc/ITTISIM.md b/doc/ITTISIM.md deleted file mode 100755 index 13fdd908469943e1585c0c014e4f7f7744659f34..0000000000000000000000000000000000000000 --- a/doc/ITTISIM.md +++ /dev/null @@ -1,48 +0,0 @@ -<table style="border-collapse: collapse; border: none;"> - <tr style="border-collapse: collapse; border: none;"> - <td style="border-collapse: collapse; border: none;"> - <a href="http://www.openairinterface.org/"> - <img src="./images/oai_final_logo.png" alt="" border=3 height=50 width=150> - </img> - </a> - </td> - <td style="border-collapse: collapse; border: none; vertical-align: center;"> - <b><font size = "5">Running L3 ITTI simulator</font></b> - </td> - </tr> -</table> - -This page is valid on the following branches: - -- `develop` starting from tag `2020.w48` - -# 1. Building the ITTI simulator. - -The ITTI simulator is available directly from the standard build. - -```bash -$ source oaienv -$ cd cmake_targets -$ sudo ./build_oai -x -w None -c -ittiSIM -``` - -# 2. Running the ITTI simulator. - -The ITTI simulator establishes ITTI-threaded communication between the gNB RRC task and the UE RRC task. - -This allows to test the sequence of NGAP/RRC/NAS messages. - -The main limitations are: - -- NAS is a simple stub that just sends and receives messages -- only initial Attach sequence - -## 2.1. Starting the ITTI simulator - -The ITTI simulator is able to run with a connected 5GC or without any. -The develop branch tag `2020.w48` only works RRC without 5GC connection. - -```bash -$ sudo -E ./ran_build/build/nr-ittisim -O gnb.conf -``` - diff --git a/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md b/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md index 1110a5bc6cd8ca5b25aaf3326894384e0c6c41a3..fc0700c6994dad76ed073bcece7326693fe43b23 100644 --- a/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md +++ b/doc/NR_SA_CN5G_gNB_B210_COTS_UE_Tutorial.md @@ -71,10 +71,6 @@ reboot # https://docs.docker.com/compose/install/ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose - -docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net -sudo service docker restart - ``` ## 2.2 OAI CN5G Setup @@ -82,39 +78,36 @@ sudo service docker restart ```bash # Git oai-cn5g-fed repository git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed -cd ~/oai-cn5g-fed -git checkout master -./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop +# Pull docker images docker pull oaisoftwarealliance/oai-amf:develop docker pull oaisoftwarealliance/oai-nrf:develop docker pull oaisoftwarealliance/oai-smf:develop docker pull oaisoftwarealliance/oai-udr:develop docker pull oaisoftwarealliance/oai-udm:develop docker pull oaisoftwarealliance/oai-ausf:develop -docker pull oaisoftwarealliance/oai-upf-vpp:develop docker pull oaisoftwarealliance/oai-spgwu-tiny:develop -docker pull oaisoftwarealliance/oai-nssf:develop +docker pull oaisoftwarealliance/trf-gen-cn5g:latest +# Tag docker images docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop -docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop -docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop +docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest ``` ## 2.3 OAI CN5G Configuration files -Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose: -- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) -- [oai_db.sql](tutorial_resources/oai_db.sql) +Download and copy configuration files: +- Copy [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) to `~/oai-cn5g-fed/docker-compose` +- Copy [oai_db.sql](tutorial_resources/oai_db.sql) to `~/oai-cn5g-fed/docker-compose/database` Change permissions on oai_db.sql to prevent mysql permission denied error: ```bash -chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql +chmod 644 ~/oai-cn5g-fed/docker-compose/database/oai_db.sql ``` ## 2.4 SIM Card @@ -175,7 +168,7 @@ cd cmake_targets ```bash cd ~/oai-cn5g-fed/docker-compose -python3 core-network.py --type start-basic --fqdn yes --scenario 1 +python3 core-network.py --type start-basic --scenario 1 ``` ## 4.2 Run OAI gNB diff --git a/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md b/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md index ed917e09eaf2a0769754ff7e736d1cde3655da67..d68057fd084e452be4619fdf8e1d7d1929751ca3 100644 --- a/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md +++ b/doc/NR_SA_CN5G_gNB_N300_COTS_UE_Tutorial.md @@ -72,10 +72,6 @@ reboot # https://docs.docker.com/compose/install/ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose - -docker network create --driver=bridge --subnet=192.168.70.128/26 -o "com.docker.network.bridge.name"="demo-oai" demo-oai-public-net -sudo service docker restart - ``` ## 2.2 OAI CN5G Setup @@ -83,39 +79,36 @@ sudo service docker restart ```bash # Git oai-cn5g-fed repository git clone https://gitlab.eurecom.fr/oai/cn5g/oai-cn5g-fed.git ~/oai-cn5g-fed -cd ~/oai-cn5g-fed -git checkout master -./scripts/syncComponents.sh --nrf-branch develop --amf-branch develop --smf-branch develop --spgwu-tiny-branch develop --ausf-branch develop --udm-branch develop --udr-branch develop --upf-vpp-branch develop --nssf-branch develop +# Pull docker images docker pull oaisoftwarealliance/oai-amf:develop docker pull oaisoftwarealliance/oai-nrf:develop docker pull oaisoftwarealliance/oai-smf:develop docker pull oaisoftwarealliance/oai-udr:develop docker pull oaisoftwarealliance/oai-udm:develop docker pull oaisoftwarealliance/oai-ausf:develop -docker pull oaisoftwarealliance/oai-upf-vpp:develop docker pull oaisoftwarealliance/oai-spgwu-tiny:develop -docker pull oaisoftwarealliance/oai-nssf:develop +docker pull oaisoftwarealliance/trf-gen-cn5g:latest +# Tag docker images docker image tag oaisoftwarealliance/oai-amf:develop oai-amf:develop docker image tag oaisoftwarealliance/oai-nrf:develop oai-nrf:develop docker image tag oaisoftwarealliance/oai-smf:develop oai-smf:develop docker image tag oaisoftwarealliance/oai-udr:develop oai-udr:develop docker image tag oaisoftwarealliance/oai-udm:develop oai-udm:develop docker image tag oaisoftwarealliance/oai-ausf:develop oai-ausf:develop -docker image tag oaisoftwarealliance/oai-upf-vpp:develop oai-upf-vpp:develop docker image tag oaisoftwarealliance/oai-spgwu-tiny:develop oai-spgwu-tiny:develop -docker image tag oaisoftwarealliance/oai-nssf:develop oai-nssf:develop +docker image tag oaisoftwarealliance/trf-gen-cn5g:latest trf-gen-cn5g:latest ``` ## 2.3 OAI CN5G Configuration files -Download and copy the configuration files to ~/oai-cn5g-fed/docker-compose: -- [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) -- [oai_db.sql](tutorial_resources/oai_db.sql) +Download and copy configuration files: +- Copy [docker-compose-basic-nrf.yaml](tutorial_resources/docker-compose-basic-nrf.yaml) to `~/oai-cn5g-fed/docker-compose` +- Copy [oai_db.sql](tutorial_resources/oai_db.sql) to `~/oai-cn5g-fed/docker-compose/database` Change permissions on oai_db.sql to prevent mysql permission denied error: ```bash -chmod 644 ~/oai-cn5g-fed/docker-compose/oai_db.sql +chmod 644 ~/oai-cn5g-fed/docker-compose/database/oai_db.sql ``` ## 2.4 SIM Card @@ -193,7 +186,7 @@ The following steps are recommended. Please change the network interface(s) as r ```bash cd ~/oai-cn5g-fed/docker-compose -python3 core-network.py --type start-basic --fqdn yes --scenario 1 +python3 core-network.py --type start-basic --scenario 1 ``` ## 4.2 Run OAI gNB diff --git a/doc/TESTBenches.md b/doc/TESTBenches.md index 547fd5a23bc6fb85849e6db0f0b8e58f38580a7e..c6a01f278d41becdfba7fcefa3713be97af469ce 100644 --- a/doc/TESTBenches.md +++ b/doc/TESTBenches.md @@ -9,19 +9,19 @@ | Machine | IP address | Lockable Resource | Function | Connected devices | | ------------- | --------------- | --------------------- | ------------------ | ----------------------------------------------------- | -| asterix | 172.21.16.127 | CI-Asterix-Usage | gNB | 173.21.19.14 | -| obelix | 172.21.16.128 | CI-Obelix-Usage | eNB, UE (5G) | 172.21.19.13, X300 (192.168.60.2), B200mini (30C51EB) | +| asterix | 172.21.16.127 | CI-Asterix-Usage | gNB (n78) | 173.21.19.14 | +| obelix | 172.21.16.128 | CI-Obelix-Usage | eNB (n40, n78), nrUE | 172.21.19.13, X300 (192.168.60.2), B200mini (30C51EB) | | porcepix | 172.21.16.136 | CI-NSA-MiniBench | Executor, EPC, 5GC | -- | | nrmodule2 | 172.21.16.139 | CI-NSA-MiniBench | Quectel | Quectel module | -| nepes | 172.21.16.137 | CI-NSA-MiniBench | gNB | B200mini (30C51D4) | +| nepes | 172.21.16.137 | CI-NSA-MiniBench | gNB (n78) | B200mini (30C51D4) | | caracal | 172.21.16.132 | CI-Caracal | gNB/phytest | N300 (192.168.10.2) | | idefix | 172.21.16.135 | CI-NSA-MiniBench | Quectel | Quectel module | -| amariue | 172.21.16.144 | CI-Amarisoft-UE-Usage | TBD | Amarisoft UE simulator | +| amariue | 172.21.16.144 | CI-Amarisoft-UE-Usage | nrUE | Amarisoft UE simulator | | bellatrix | 192.168.117.115 | CI-RAN-VM-Deployment | Executor | -- | | nano | 192.168.12.62 | CI-Bench-1-Phones | EPC, adb | 2x COTS (adb) | | hutch | 192.168.12.19 | CI-Bench-1-Phones | eNB (B7) | B200mini (30C5239) | | starsky | 192.168.12.18 | CI-Bench-1-Phones | eNB (B40) | b200mini (30A3E3C) | -| carabe | 192.168.12.211 | CI-Bench-2-OAI-Phone | UE 4G (B) | B200mini (30AE8C9) | +| carabe | 192.168.12.211 | CI-Bench-2-OAI-Phone | UE (B7UE) | B200mini (30AE8C9) | Note: The available resources, and their current usage, is indicated here: - [Lockable resources of jenkins-oai](https://jenkins-oai.eurecom.fr/lockable-resources/): @@ -40,7 +40,7 @@ Note: The available resources, and their current usage, is indicated here: ### OTA Testbench -[Proper image to be followed up. TBD: add antennas/circulators] +**Purpose**: Over-the-air 4G/5G (NSA/SA) tests Note: obelix and porcepix are both used in the OTA testbench and the 5G NSA/Faraday Cage testbench! @@ -89,7 +89,10 @@ Webhook currently only ping - [RAN-NSA-B200-Module-LTEBOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-NSA-B200-Module-LTEBOX-Container/) - obelix + B200, nepes + B200, idefix + Quectel, porcepix w/ ltebox - - basic NSA test, known to be instable + - basic NSA test +- [RAN-SA-B200-Module-SABOX-Container](https://jenkins-oai.eurecom.fr/job/RAN-SA-B200-Module-SABOX-Container/) + - obelix + B200, nepes + B200, idefix + Quectel, porcepix w/ sabox + - basic SA test (40 MHz TDD) - [RAN-PhySim-Cluster](https://jenkins-oai.eurecom.fr/job/RAN-PhySim-Cluster/) - asterix (`Asterix-OC-oaicicd-session` resource), tests in OpenShift Cluster - unitary simulators (`nr_dlsim`, etc.) diff --git a/doc/testbenches_doc_resources/4g-faraday-bench.pdf b/doc/testbenches_doc_resources/4g-faraday-bench.pdf index 7e31789e9acb9a3cc05719d98304966708925ff9..f6f7b078e67c61044004c70a92c729b14079cafc 100644 Binary files a/doc/testbenches_doc_resources/4g-faraday-bench.pdf and b/doc/testbenches_doc_resources/4g-faraday-bench.pdf differ diff --git a/doc/testbenches_doc_resources/4g-faraday-bench.png b/doc/testbenches_doc_resources/4g-faraday-bench.png index c69065a369c3f94b3e8a856b892f6b3bed2b42df..598715a19347b8f8e277d38a7132331555978c55 100644 Binary files a/doc/testbenches_doc_resources/4g-faraday-bench.png and b/doc/testbenches_doc_resources/4g-faraday-bench.png differ diff --git a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf index f6d960c1a257651b538b404f8f019438d3014f15..1b921e64370954673e45ed70ff1643462f4774ed 100644 Binary files a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf and b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.pdf differ diff --git a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png index c677b598e9894a1bbf0e1e7321497e4c51e6fb17..006e6ab347d2dcd3283f5cdb59c65d1d1ba1ea8e 100644 Binary files a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png and b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.png differ diff --git a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex index 66b52f7f697b76a0922370b87353573f30cbee9b..a9f12fe3df265a1b6aabaa46808747b87c247b30 100644 --- a/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex +++ b/doc/testbenches_doc_resources/5g-nsa-faraday-bench.tex @@ -30,7 +30,7 @@ \draw (obelix) -- (b210o); \node[above right=0.35cm of faraday.south west] (antn) {\includegraphics[width=0.3cm]{antenna}}; - \draw (b210n) -| node [pos=0.2, duplexer] {B78} (antn); + \draw (b210n) -| node [pos=0.2, duplexer] {n78} (antn); \node[left=5cm of faraday, label=above:porcepix] (porcepix) {\includegraphics[width=1.2cm]{server}}; diff --git a/doc/testbenches_doc_resources/5g-ota-bench.pdf b/doc/testbenches_doc_resources/5g-ota-bench.pdf index e4d4c15e394ad4664d6eea6580db9952d8d7e341..121969030e64e03ac0e4fedc9ba4fc1c692de71c 100644 Binary files a/doc/testbenches_doc_resources/5g-ota-bench.pdf and b/doc/testbenches_doc_resources/5g-ota-bench.pdf differ diff --git a/doc/testbenches_doc_resources/5g-ota-bench.png b/doc/testbenches_doc_resources/5g-ota-bench.png index c93de7ec6fde10508184eff7f68215c72d3924ec..86ae6b2b6413025f922887d4e0a17c934acf0297 100644 Binary files a/doc/testbenches_doc_resources/5g-ota-bench.png and b/doc/testbenches_doc_resources/5g-ota-bench.png differ diff --git a/doc/testbenches_doc_resources/5g-ota-bench.tex b/doc/testbenches_doc_resources/5g-ota-bench.tex index cfd0bda22d60c4b97b6913f5bd8923970f1c4bd2..c3a524fb0ae276564625f8fcdb128352957aa941 100644 --- a/doc/testbenches_doc_resources/5g-ota-bench.tex +++ b/doc/testbenches_doc_resources/5g-ota-bench.tex @@ -21,7 +21,7 @@ edge (porcepix); \node[right=0.3cm of asterix, label=above:N310] (n310a) {\includegraphics[width=1.5cm]{n310}} edge (asterix); - \node[right=.2cm of n310a, duplexer] (b78o) {B78} edge (n310a); + \node[right=.2cm of n310a, duplexer] (b78o) {n78} edge (n310a); \node[below right=-0.1cm and 0.35cm of b78o.east] (anto1) {\includegraphics[width=0.3cm]{antenna}} edge (b78o); \node[above right=-0.1cm and 0.35cm of b78o.east] (anto2) @@ -32,20 +32,20 @@ edge (porcepix); \node[above right=-0.5cm and 0.3cm of obelix, label=above:N310] (n310o) {\includegraphics[width=1.5cm]{n310}} edge (obelix); - \node[right=.2cm of n310o, duplexer] (b78o) {B40} edge (n310o); + \node[right=.2cm of n310o, duplexer] (b78o) {n40} edge (n310o); \node[below right=-0.1cm and 0.35cm of b78o.east] (anto1) {\includegraphics[width=0.3cm]{antenna}} edge (b78o); \node[above right=-0.1cm and 0.35cm of b78o.east] (anto2) {\includegraphics[width=0.3cm]{antenna}} edge (b78o); \node[below right=-0.5cm and 0.3cm of obelix, label=above:X310] (x310o) {\includegraphics[width=1.5cm]{x310}} edge (obelix); - \node[right=.2cm of x310o, duplexer] (b78o) {B78} edge (x310o); + \node[right=.2cm of x310o, duplexer] (b78o) {n78} edge (x310o); \node[below right=-0.1cm and 0.35cm of b78o.east] (anto1) {\includegraphics[width=0.3cm]{antenna}} edge (b78o); \node[above right=-0.1cm and 0.35cm of b78o.east] (anto2) {\includegraphics[width=0.3cm]{antenna}} edge (b78o); - \node[right=5.0cm of n310o, label=above:RM500Q-GL] (quectel) + \node[above right=-1.3cm and 5.0cm of n310a.east, label=above:RM500Q-GL] (quectel) {\includegraphics[height=1.2cm]{quectel}}; \node[above left=-0.1cm and 0.8cm of quectel.west] (aq2) {\includegraphics[width=0.3cm]{antenna}} edge (quectel); @@ -59,5 +59,10 @@ {\includegraphics[width=1.2cm]{server}} edge (quectel); + \node[above right=-0.3cm and 5.0cm of x310o.east, label=above:amariue] (amariue) + {\includegraphics[height=1.2cm]{server}}; + \node[left=0.8cm of amariue.west] (aa1) + {\includegraphics[width=0.3cm]{antenna}} edge (amariue); + \end{tikzpicture} \end{document} diff --git a/doc/testing_gnb_w_cots_ue_resources/gnb.conf b/doc/testing_gnb_w_cots_ue_resources/gnb.conf index c96d2074456e2db36880f9faadb10468d1d33dfd..206e1b4f02b3a357b54f4242546fc4a01473cec5 100755 --- a/doc/testing_gnb_w_cots_ue_resources/gnb.conf +++ b/doc/testing_gnb_w_cots_ue_resources/gnb.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; - pdsch_AntennaPorts = 1; servingCellConfigCommon = ( { diff --git a/doc/tutorial_resources/docker-compose-basic-nrf.yaml b/doc/tutorial_resources/docker-compose-basic-nrf.yaml index 6750cb78bec7d39448a0f5cc562ff76f61e87ada..cd1e957ad8b09d7f4d490bd0af3c0dcd75e56fbd 100644 --- a/doc/tutorial_resources/docker-compose-basic-nrf.yaml +++ b/doc/tutorial_resources/docker-compose-basic-nrf.yaml @@ -4,8 +4,8 @@ services: container_name: "mysql" image: mysql:5.7 volumes: - - ./oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql - - ./mysql-healthcheck2.sh:/tmp/mysql-healthcheck.sh + - ./database/oai_db.sql:/docker-entrypoint-initdb.d/oai_db.sql + - ./healthscripts/mysql-healthcheck2.sh:/tmp/mysql-healthcheck.sh environment: - TZ=Europe/Paris - MYSQL_DATABASE=oai_db @@ -21,35 +21,45 @@ services: public_net: ipv4_address: 192.168.70.131 oai-udr: - container_name: oai-udr + container_name: "oai-udr" image: oai-udr:develop environment: - TZ=Europe/Paris - INSTANCE=0 - PID_DIRECTORY=/var/run + - UDR_NAME=OAI_UDR - UDR_INTERFACE_NAME_FOR_NUDR=eth0 - UDR_INTERFACE_PORT_FOR_NUDR=80 - UDR_INTERFACE_HTTP2_PORT_FOR_NUDR=8080 + - USE_HTTP2=no - UDR_API_VERSION=v1 - MYSQL_IPV4_ADDRESS=192.168.70.131 - MYSQL_USER=test - MYSQL_PASS=test + - DB_CONNECTION_TIMEOUT=300 # Reset the connection to the DB after expiring the timeout (in second) currently can't be changed - MYSQL_DB=oai_db - WAIT_MYSQL=120 + - USE_FQDN_DNS=yes + - REGISTER_NRF=yes + - NRF_IPV4_ADDRESS=192.168.70.130 + - NRF_PORT=80 + - NRF_API_VERSION=v1 + - NRF_FQDN=oai-nrf depends_on: - mysql + - oai-nrf networks: public_net: ipv4_address: 192.168.70.136 volumes: - - ./udr-healthcheck.sh:/openair-udr/bin/udr-healthcheck.sh + - ./healthscripts/udr-healthcheck.sh:/openair-udr/bin/udr-healthcheck.sh healthcheck: test: /bin/bash -c "/openair-udr/bin/udr-healthcheck.sh" interval: 10s timeout: 5s retries: 5 oai-udm: - container_name: oai-udm + container_name: "oai-udm" image: oai-udm:develop environment: - TZ=Europe/Paris @@ -58,26 +68,33 @@ services: - UDM_NAME=OAI_UDM - SBI_IF_NAME=eth0 - SBI_PORT=80 + - SBI_HTTP2_PORT=8080 + - USE_HTTP2=no - UDM_VERSION_NB=v1 - USE_FQDN_DNS=yes - UDR_IP_ADDRESS=192.168.70.136 - UDR_PORT=80 - UDR_VERSION_NB=v1 - UDR_FQDN=oai-udr + - REGISTER_NRF=yes + - NRF_IPV4_ADDRESS=192.168.70.130 + - NRF_PORT=80 + - NRF_API_VERSION=v1 + - NRF_FQDN=oai-nrf depends_on: - oai-udr networks: public_net: ipv4_address: 192.168.70.137 volumes: - - ./udm-healthcheck.sh:/openair-udm/bin/udm-healthcheck.sh + - ./healthscripts/udm-healthcheck.sh:/openair-udm/bin/udm-healthcheck.sh healthcheck: test: /bin/bash -c "/openair-udm/bin/udm-healthcheck.sh" interval: 10s timeout: 5s retries: 5 oai-ausf: - container_name: oai-ausf + container_name: "oai-ausf" image: oai-ausf:develop environment: - TZ=Europe/Paris @@ -86,18 +103,25 @@ services: - AUSF_NAME=OAI_AUSF - SBI_IF_NAME=eth0 - SBI_PORT=80 + - USE_HTTP2 + - SBI_HTTP2_PORT - USE_FQDN_DNS=yes - UDM_IP_ADDRESS=192.168.70.137 - UDM_PORT=80 - UDM_VERSION_NB=v1 - UDM_FQDN=oai-udm + - REGISTER_NRF=yes + - NRF_IPV4_ADDRESS=192.168.70.130 + - NRF_PORT=80 + - NRF_API_VERSION=v1 + - NRF_FQDN=oai-nrf depends_on: - oai-udm networks: public_net: ipv4_address: 192.168.70.138 volumes: - - ./ausf-healthcheck.sh:/openair-ausf/bin/ausf-healthcheck.sh + - ./healthscripts/ausf-healthcheck.sh:/openair-ausf/bin/ausf-healthcheck.sh healthcheck: test: /bin/bash -c "/openair-ausf/bin/ausf-healthcheck.sh" interval: 10s @@ -107,9 +131,10 @@ services: container_name: "oai-nrf" image: oai-nrf:develop environment: + - TZ=Europe/Paris - NRF_INTERFACE_NAME_FOR_SBI=eth0 - NRF_INTERFACE_PORT_FOR_SBI=80 - - NRF_INTERFACE_HTTP2_PORT_FOR_SBI=9090 + - NRF_INTERFACE_HTTP2_PORT_FOR_SBI=8080 - NRF_API_VERSION=v1 - INSTANCE=0 - PID_DIRECTORY=/var/run @@ -117,7 +142,7 @@ services: public_net: ipv4_address: 192.168.70.130 volumes: - - ./nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh + - ./healthscripts/nrf-healthcheck.sh:/openair-nrf/bin/nrf-healthcheck.sh healthcheck: test: /bin/bash -c "/openair-nrf/bin/nrf-healthcheck.sh" interval: 10s @@ -146,9 +171,7 @@ services: - PLMN_SUPPORT_MNC=99 - PLMN_SUPPORT_TAC=0x0001 - SST_0=1 - - SD_0=1 - - SST_1=1 - - SD_1=12 + - SD_0=0x1 - AMF_INTERFACE_NAME_FOR_NGAP=eth0 - AMF_INTERFACE_NAME_FOR_N11=eth0 - SMF_INSTANCE_ID_0=1 @@ -168,22 +191,30 @@ services: - OPERATOR_KEY=1006020f0a478bf6b699f15c062e42b3 - NRF_IPV4_ADDRESS=192.168.70.130 - NRF_PORT=80 + - EXTERNAL_NRF=no - NF_REGISTRATION=yes - SMF_SELECTION=yes - USE_FQDN_DNS=yes - EXTERNAL_AUSF=yes + - EXTERNAL_UDM=no + - EXTERNAL_NSSF=no + - USE_HTTP2=no - NRF_API_VERSION=v1 - NRF_FQDN=oai-nrf - AUSF_IPV4_ADDRESS=192.168.70.138 - AUSF_PORT=80 - AUSF_API_VERSION=v1 - AUSF_FQDN=oai-ausf + - UDM_IPV4_ADDRESS=192.168.70.137 + - UDM_PORT=80 + - UDM_API_VERSION=v2 + - UDM_FQDN=oai-udm depends_on: - mysql - oai-nrf - oai-ausf volumes: - - ./amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh + - ./healthscripts/amf-healthcheck.sh:/openair-amf/bin/amf-healthcheck.sh healthcheck: test: /bin/bash -c "/openair-amf/bin/amf-healthcheck.sh" interval: 10s @@ -212,26 +243,35 @@ services: - AMF_FQDN=oai-amf - UDM_IPV4_ADDRESS=192.168.70.137 - UDM_PORT=80 - - UDM_API_VERSION=v1 + - UDM_API_VERSION=v2 - UDM_FQDN=oai-udm - UPF_IPV4_ADDRESS=192.168.70.134 - UPF_FQDN_0=oai-spgwu - NRF_IPV4_ADDRESS=192.168.70.130 - NRF_PORT=80 - NRF_API_VERSION=v1 - - USE_LOCAL_SUBSCRIPTION_INFO=yes + - USE_LOCAL_SUBSCRIPTION_INFO=yes #Set to yes if SMF uses local subscription information instead of from an UDM + - USE_NETWORK_INSTANCE=no #Set yes if network instance is to be used for given UPF - NRF_FQDN=oai-nrf - REGISTER_NRF=yes - DISCOVER_UPF=yes - USE_FQDN_DNS=yes - - DNN_RANGE1=12.1.1.2 - 12.1.1.128 - - DNN_RANGE0=12.2.1.2 - 12.2.1.128 - - DNN_NI1=oai + - HTTP_VERSION=1 # Default: 1 + - UE_MTU=1500 + - DNN_NI0=oai + - TYPE0=IPv4 + - DNN_RANGE0=12.1.1.2 - 12.1.1.253 + - NSSAI_SST0=1 + - NSSAI_SD0=0x1 + - SESSION_AMBR_UL0=1000Mbps + - SESSION_AMBR_DL0=1000Mbps + - DEFAULT_CSCF_IPV4_ADDRESS=127.0.0.1 # only needed when ims is being used + - ENABLE_USAGE_REPORTING=no # Set yes if UE USAGE REPORTING is to be done at UPF depends_on: - oai-nrf - oai-amf volumes: - - ./smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh + - ./healthscripts/smf-healthcheck.sh:/openair-smf/bin/smf-healthcheck.sh healthcheck: test: /bin/bash -c "/openair-smf/bin/smf-healthcheck.sh" interval: 10s @@ -258,17 +298,23 @@ services: - MNC03=099 - TAC=1 - GW_ID=1 + - THREAD_S1U_PRIO=80 + - S1U_THREADS=8 + - THREAD_SX_PRIO=81 + - SX_THREADS=1 + - THREAD_SGI_PRIO=80 + - SGI_THREADS=8 - REALM=openairinterface.org - ENABLE_5G_FEATURES=yes - REGISTER_NRF=yes - - USE_FQDN_NRF=no + - USE_FQDN_NRF=yes - UPF_FQDN_5G=oai-spgwu - NRF_IPV4_ADDRESS=192.168.70.130 - NRF_PORT=80 - NRF_API_VERSION=v1 - NRF_FQDN=oai-nrf - NSSAI_SST_0=1 - - NSSAI_SD_0=1 + - NSSAI_SD_0=0x1 - DNN_0=oai depends_on: - oai-nrf @@ -280,7 +326,7 @@ services: - ALL privileged: true volumes: - - ./spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh + - ./healthscripts/spgwu-healthcheck.sh:/openair-spgwu-tiny/bin/spgwu-healthcheck.sh healthcheck: test: /bin/bash -c "/openair-spgwu-tiny/bin/spgwu-healthcheck.sh" interval: 10s @@ -290,12 +336,10 @@ services: public_net: ipv4_address: 192.168.70.134 oai-ext-dn: - image: ubuntu:bionic + image: trf-gen-cn5g:latest privileged: true container_name: oai-ext-dn entrypoint: /bin/bash -c \ - "apt update; apt install -y iptables iproute2 iperf iperf3 iputils-ping;"\ - "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;"\ "ip route add 12.1.1.0/24 via 192.168.70.134 dev eth0; sleep infinity" depends_on: - oai-spgwu @@ -303,14 +347,14 @@ services: public_net: ipv4_address: 192.168.70.135 networks: + # public_net: + # external: + # name: demo-oai-public-net public_net: - external: - name: demo-oai-public-net -# public_net: -# driver: bridge -# name: demo-oai-public-net -# ipam: -# config: -# - subnet: 192.168.70.128/26 -# driver_opts: -# com.docker.network.bridge.name: "demo-oai" + driver: bridge + name: demo-oai-public-net + ipam: + config: + - subnet: 192.168.70.128/26 + driver_opts: + com.docker.network.bridge.name: "demo-oai" diff --git a/doc/tutorial_resources/oai_db.sql b/doc/tutorial_resources/oai_db.sql index e019c60e8623b9779e3f6d43053fd3ed69a31472..fb8f4b20edc1a81bda0d4f1bf89df18ab7ec782c 100644 --- a/doc/tutorial_resources/oai_db.sql +++ b/doc/tutorial_resources/oai_db.sql @@ -151,10 +151,13 @@ CREATE TABLE `AuthenticationSubscription` ( -- INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES -('208950000000031', '5G_AKA', '0C0A34601D4F07677303652C0462535B', '0C0A34601D4F07677303652C0462535B', '{\"sqn\": \"000000000020\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', '63bfa50ee6523365ff14c1f45f88737d', NULL, NULL, NULL, NULL, '208950000000031'); - + ('2089900007487', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '2089900007487'); +INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES + ('208990000000001', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000001'); INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES -('208990000000001', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000020\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000001'); + ('208990000000002', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000002'); +INSERT INTO `AuthenticationSubscription` (`ueid`, `authenticationMethod`, `encPermanentKey`, `protectionParameterId`, `sequenceNumber`, `authenticationManagementField`, `algorithmId`, `encOpcKey`, `encTopcKey`, `vectorGenerationInHss`, `n5gcAuthMethod`, `rgAuthenticationInd`, `supi`) VALUES + ('208990000000003', '5G_AKA', 'fec86ba6eb707ed08905757b1bb44b8f', 'fec86ba6eb707ed08905757b1bb44b8f', '{\"sqn\": \"000000000000\", \"sqnScheme\": \"NON_TIME_BASED\", \"lastIndexes\": {\"ausf\": 0}}', '8000', 'milenage', 'C42449363BBAD02B66D16BC975D77CC1', NULL, NULL, NULL, NULL, '208990000000003'); -- -------------------------------------------------------- @@ -203,6 +206,19 @@ CREATE TABLE `SessionManagementSubscriptionData` ( `3gppChargingCharacteristics` varchar(50) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-- +-- Dumping data for table `SessionManagementSubscriptionData` +-- + +INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES + ('2089900007487', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.2\"}]}}'); +INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES + ('208990000000001', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.2\"}]}}'); +INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES + ('208990000000002', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.3\"}]}}'); +INSERT INTO `SessionManagementSubscriptionData` (`ueid`, `servingPlmnid`, `singleNssai`, `dnnConfigurations`) VALUES + ('208990000000003', '20899', '{\"sst\": 1, \"sd\": \"1\"}','{\"oai\":{\"pduSessionTypes\":{ \"defaultSessionType\": \"IPV4\"},\"sscModes\": {\"defaultSscMode\": \"SSC_MODE_1\"},\"5gQosProfile\": {\"5qi\": 6,\"arp\":{\"priorityLevel\": 1,\"preemptCap\": \"NOT_PREEMPT\",\"preemptVuln\":\"NOT_PREEMPTABLE\"},\"priorityLevel\":1},\"sessionAmbr\":{\"uplink\":\"1000Mbps\", \"downlink\":\"1000Mbps\"},\"staticIpAddress\":[{\"ipv4Addr\": \"12.1.1.4\"}]}}'); + -- -------------------------------------------------------- -- diff --git a/docker/scripts/generateTemplate.py b/docker/scripts/generateTemplate.py index 850bb535a52abd6bc08159d72e0593d78b03bc2d..ec8f32ec6e849c55643e856b07775d7cdffe9834 100644 --- a/docker/scripts/generateTemplate.py +++ b/docker/scripts/generateTemplate.py @@ -60,6 +60,7 @@ def main(): "rcc.band40.tm1.25PRB": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gnb.band78.tm1.fr1.106PRB.usrpb210.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gnb.band78.sa.fr1.106PRB.usrpn310.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', + "gnb.sa.band78.fr1.106PRB.usrpb210.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gnb.sa.band66.fr1.106PRB.usrpn300.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gNB_SA_CU.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', "gNB_SA_DU.conf": f'{data[0]["paths"]["dest_dir"]}/{outputfilename}', diff --git a/docker/scripts/gnb_entrypoint.sh b/docker/scripts/gnb_entrypoint.sh index dd6256609c8085aec0b6b0c68e63caa2fe61d601..6deff8da109fa7410e0c73b037eb6b04fbff8a19 100755 --- a/docker/scripts/gnb_entrypoint.sh +++ b/docker/scripts/gnb_entrypoint.sh @@ -10,6 +10,7 @@ THREAD_PARALLEL_CONFIG=${THREAD_PARALLEL_CONFIG:-PARALLEL_SINGLE_THREAD} if [[ -v USE_NSA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.nsa.tdd.conf $PREFIX/etc/gnb.conf; fi if [[ -v USE_SA_TDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.tdd.conf $PREFIX/etc/gnb.conf; fi +if [[ -v USE_SA_TDD_MONO_B2XX ]]; then cp $PREFIX/etc/gnb.sa.tdd.b2xx.conf $PREFIX/etc/gnb.conf; fi if [[ -v USE_SA_FDD_MONO ]]; then cp $PREFIX/etc/gnb.sa.fdd.conf $PREFIX/etc/gnb.conf; fi if [[ -v USE_SA_CU ]]; then cp $PREFIX/etc/gnb.sa.cu.conf $PREFIX/etc/gnb.conf; fi if [[ -v USE_SA_TDD_CU ]]; then cp $PREFIX/etc/gnb.sa.du.tdd.conf $PREFIX/etc/gnb.conf; fi @@ -17,6 +18,10 @@ if [[ -v USE_SA_NFAPI_VNF ]]; then cp $PREFIX/etc/gnb.sa.nfapi.vnf.conf $PREFIX/ # Sometimes, the templates are not enough. We mount a conf file on $PREFIX/etc. It can be a template itself. if [[ -v USE_VOLUMED_CONF ]]; then cp $PREFIX/etc/mounted.conf $PREFIX/etc/gnb.conf; fi +# Resolve AMF FQDN +AMF_FQDN=${AMF_FQDN:-oai-amf-svc} +if ($USE_FQDN); then AMF_IP_ADDRESS=(`getent hosts $AMF_FQDN | awk '{print $1}'`); fi + # Only this template will be manipulated CONFIG_FILES=`ls $PREFIX/etc/gnb.conf || true` diff --git a/docker/scripts/gnb_parameters.yaml b/docker/scripts/gnb_parameters.yaml index d5942f2c9b4559d6db4b8e0eb76b1b7a01d27e53..420559ff3f758311222935f76a5e02f8b908934f 100644 --- a/docker/scripts/gnb_parameters.yaml +++ b/docker/scripts/gnb_parameters.yaml @@ -94,6 +94,36 @@ - key: parallel_config env: "@THREAD_PARALLEL_CONFIG@" + - filePrefix: gnb.sa.band78.fr1.106PRB.usrpb210.conf + outputfilename: "gnb.sa.tdd.b2xx.conf" + config: + - key: Active_gNBs + env: "@GNB_NAME@" + - key: gNB_name + env: "@GNB_NAME@" + - key: mcc + env: "@MCC@" + - key: mnc + env: "@MNC@" + - key: mnc_length + env: "@MNC_LENGTH@" + - key: tracking_area_code + env: "@TAC@" + - key: sst + env: "@NSSAI_SST@" + - key: ipv4 + env: "@AMF_IP_ADDRESS@" + - key: GNB_INTERFACE_NAME_FOR_NG_AMF + env: "@GNB_NGA_IF_NAME@" + - key: GNB_IPV4_ADDRESS_FOR_NG_AMF + env: "@GNB_NGA_IP_ADDRESS@" + - key: GNB_INTERFACE_NAME_FOR_NGU + env: "@GNB_NGU_IF_NAME@" + - key: GNB_IPV4_ADDRESS_FOR_NGU + env: "@GNB_NGU_IP_ADDRESS@" + - key: parallel_config + env: "@THREAD_PARALLEL_CONFIG@" + - filePrefix: gnb.sa.band66.fr1.106PRB.usrpn300.conf outputfilename: "gnb.sa.fdd.conf" config: diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index b51e5b90981dcbe293652786815a8ea727cd4783..a4070a94828f63b6910433dbb63d09cbf891f0ed 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -466,7 +466,7 @@ void init_gNB_Tpool(int inst) { pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx); // to unblock the process in the beginning } - if (!get_softmodem_params()->emulate_l1) + if ((!get_softmodem_params()->emulate_l1) && (!IS_SOFTMODEM_NOSTATS_BIT)) threadCreate(&proc->L1_stats_thread,nrL1_stats_thread,(void*)gNB,"L1_stats",-1,OAI_PRIORITY_RT_LOW); threadCreate(&proc->pthread_tx_reorder, tx_reorder_thread, (void *)gNB, "thread_tx_reorder", -1, OAI_PRIORITY_RT_MAX); diff --git a/executables/nr-ru.c b/executables/nr-ru.c index ad018b17ab010d765793e7e63e52313776741b36..3ddca7419402abf3e9d0570246b03d06ab54205f 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -31,6 +31,7 @@ #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all +#include "common/utils/nr/nr_common.h" #include "common/utils/assertions.h" #include "common/utils/system.h" #include "common/ran_context.h" @@ -809,226 +810,13 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { int mu = config->ssb_config.scs_common.value; int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; - if (mu == NR_MU_0) { - switch(N_RB) { - case 270: - if (fp->threequarter_fs) { - cfg->sample_rate=92.16e6; - cfg->samples_per_frame = 921600; - cfg->tx_bw = 50e6; - cfg->rx_bw = 50e6; - } else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 50e6; - cfg->rx_bw = 50e6; - } - case 216: - if (fp->threequarter_fs) { - cfg->sample_rate=46.08e6; - cfg->samples_per_frame = 460800; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } - else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } - break; - case 160: //30 MHz - case 133: //25 MHz - if (fp->threequarter_fs) { - AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",N_RB); - } - else { - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } - case 106: - if (fp->threequarter_fs) { - cfg->sample_rate=23.04e6; - cfg->samples_per_frame = 230400; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } - else { - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } - break; - case 52: - if (fp->threequarter_fs) { - cfg->sample_rate=11.52e6; - cfg->samples_per_frame = 115200; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - else { - cfg->sample_rate=15.36e6; - cfg->samples_per_frame = 153600; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - case 25: - if (fp->threequarter_fs) { - cfg->sample_rate=5.76e6; - cfg->samples_per_frame = 57600; - cfg->tx_bw = 5e6; - cfg->rx_bw = 5e6; - } - else { - cfg->sample_rate=7.68e6; - cfg->samples_per_frame = 76800; - cfg->tx_bw = 5e6; - cfg->rx_bw = 5e6; - } - break; - default: - AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); - } - } else if (mu == NR_MU_1) { - switch(N_RB) { - - case 273: - if (fp->threequarter_fs) { - cfg->sample_rate=184.32e6; - cfg->samples_per_frame = 1843200; - cfg->tx_bw = 100e6; - cfg->rx_bw = 100e6; - } else { - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 100e6; - cfg->rx_bw = 100e6; - } - break; - case 217: - if (fp->threequarter_fs) { - cfg->sample_rate=92.16e6; - cfg->samples_per_frame = 921600; - cfg->tx_bw = 80e6; - cfg->rx_bw = 80e6; - } else { - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 80e6; - cfg->rx_bw = 80e6; - } - break; - case 162 : - if (fp->threequarter_fs) { - AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",N_RB); - } - else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 60e6; - cfg->rx_bw = 60e6; - } - - break; - - case 133 : - if (fp->threequarter_fs) { - AssertFatal(1==0,"N_RB %d cannot use 3/4 sampling\n",N_RB); - } - else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 50e6; - cfg->rx_bw = 50e6; - } - - break; - case 106: - if (fp->threequarter_fs) { - cfg->sample_rate=46.08e6; - cfg->samples_per_frame = 460800; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } - else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } - break; - case 51: - if (fp->threequarter_fs) { - cfg->sample_rate=23.04e6; - cfg->samples_per_frame = 230400; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } - else { - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 20e6; - cfg->rx_bw = 20e6; - } - break; - case 24: - if (fp->threequarter_fs) { - cfg->sample_rate=11.52e6; - cfg->samples_per_frame = 115200; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - else { - cfg->sample_rate=15.36e6; - cfg->samples_per_frame = 153600; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - break; - default: - AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); - } - } else if (mu == NR_MU_3) { - switch(N_RB) { - case 66: - if (fp->threequarter_fs) { - cfg->sample_rate=184.32e6; - cfg->samples_per_frame = 1843200; - cfg->tx_bw = 100e6; - cfg->rx_bw = 100e6; - } else { - cfg->sample_rate = 122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 100e6; - cfg->rx_bw = 100e6; - } - - break; - - case 32: - if (fp->threequarter_fs) { - cfg->sample_rate=92.16e6; - cfg->samples_per_frame = 921600; - cfg->tx_bw = 50e6; - cfg->rx_bw = 50e6; - } else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 50e6; - cfg->rx_bw = 50e6; - } - - break; - - default: - AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); - } - } else { - AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); - } + get_samplerate_and_bw(mu, + N_RB, + fp->threequarter_fs, + &cfg->sample_rate, + &cfg->samples_per_frame, + &cfg->tx_bw, + &cfg->rx_bw); if (config->cell_config.frame_duplex_type.value==TDD) cfg->duplex_mode = duplex_mode_TDD; diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index e7eda6a612938cd08c08133b5dd6e67607a4a8e5..edf43f9207cd7308de2bec09a7ef677be9b4b128 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -61,9 +61,6 @@ extern void set_function_spec_param(RU_t *ru); extern void reset_opp_meas(void); extern void print_opp_meas(void); - -extern void init_fep_thread(PHY_VARS_gNB *); - void init_gNB_afterRU(void); extern int stop_L1L2(module_id_t gnb_id); diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 01e6c6213845563d4618848c7a34d1dedb7b66e9..7b39dfdcaa779049ff32161eb9e9d1bc0966bac8 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -1109,8 +1109,10 @@ void init_NR_UE_threads(int nb_inst) { LOG_I(PHY,"Intializing UE Threads for instance %d (%p,%p)...\n",inst,PHY_vars_UE_g[inst],PHY_vars_UE_g[inst][0]); threadCreate(&threads[inst], UE_thread, (void *)UE, "UEthread", -1, OAI_PRIORITY_RT_MAX); - pthread_t stat_pthread; - threadCreate(&stat_pthread, nrL1_UE_stats_thread, UE, "L1_UE_stats", -1, OAI_PRIORITY_RT_LOW); + if (!IS_SOFTMODEM_NOSTATS_BIT) { + pthread_t stat_pthread; + threadCreate(&stat_pthread, nrL1_UE_stats_thread, UE, "L1_UE_stats", -1, OAI_PRIORITY_RT_LOW); + } } } diff --git a/executables/softmodem-common.c b/executables/softmodem-common.c index eba5f3469155259337a32b37929b9af0d6d053e5..6229fbbbc208b2af626e3c4a368d712068a685c9 100644 --- a/executables/softmodem-common.c +++ b/executables/softmodem-common.c @@ -85,6 +85,7 @@ char *get_softmodem_function(uint64_t *sofmodemfunc_mask_ptr) { } void get_common_options(uint32_t execmask) { + int32_t stats_disabled = 0; uint32_t online_log_messages=0; uint32_t glog_level=0 ; uint32_t start_telnetsrv = 0, start_telnetclt = 0; @@ -149,6 +150,8 @@ void get_common_options(uint32_t execmask) { if(worker_config != NULL) set_worker_conf(worker_config); nfapi_setmode(nfapi_mode); + if (stats_disabled) + set_softmodem_optmask(SOFTMODEM_NOSTATS_BIT); } void softmodem_printresources(int sig, telnet_printfunc_t pf) { struct rusage usage; diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index 0a4a474a6ca40a2bd6ea14cfb1e74fd5ba310bda..3cc248d7afdf3be57b049f9d5db99373366b64dd 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -101,6 +101,7 @@ extern "C" #define CONFIG_HLP_NFAPI "Change the nFAPI mode for NR\n" #define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n" #define CONFIG_HLP_CONTINUOUS_TX "perform continuous transmission, even in TDD mode (to work around USRP issues)\n" +#define CONFIG_HLP_STATS_DISABLE "disable globally the stats generation and persistence" /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ /* command line parameters common to eNodeB and UE */ @@ -171,6 +172,7 @@ extern int usrp_tx_thread; {"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \ {"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, iptr:&EMULATE_L1, defintval:0, TYPE_INT, 0}, \ {"continuous-tx", CONFIG_HLP_CONTINUOUS_TX,PARAMFLAG_BOOL, iptr:&CONTINUOUS_TX, defintval:0, TYPE_INT, 0}, \ + {"disable-stats", CONFIG_HLP_STATS_DISABLE, PARAMFLAG_BOOL, iptr:&stats_disabled, defintval:0, TYPE_INT, 0}, \ } #define CONFIG_HLP_NSA "Enable NSA mode \n" @@ -217,6 +219,7 @@ extern int usrp_tx_thread; #define SOFTMODEM_GNB_BIT (1<<21) #define SOFTMODEM_4GUE_BIT (1<<22) #define SOFTMODEM_5GUE_BIT (1<<23) +#define SOFTMODEM_NOSTATS_BIT (1<<24) #define SOFTMODEM_FUNC_BITS (SOFTMODEM_ENB_BIT | SOFTMODEM_GNB_BIT | SOFTMODEM_5GUE_BIT | SOFTMODEM_4GUE_BIT) #define MAPPING_SOFTMODEM_FUNCTIONS {{"enb",SOFTMODEM_ENB_BIT},{"gnb",SOFTMODEM_GNB_BIT},{"4Gue",SOFTMODEM_4GUE_BIT},{"5Gue",SOFTMODEM_5GUE_BIT}} @@ -234,6 +237,7 @@ extern int usrp_tx_thread; #define IS_SOFTMODEM_GNB_BIT ( get_softmodem_optmask() & SOFTMODEM_GNB_BIT) #define IS_SOFTMODEM_4GUE_BIT ( get_softmodem_optmask() & SOFTMODEM_4GUE_BIT) #define IS_SOFTMODEM_5GUE_BIT ( get_softmodem_optmask() & SOFTMODEM_5GUE_BIT) +#define IS_SOFTMODEM_NOSTATS_BIT ( get_softmodem_optmask() & SOFTMODEM_NOSTATS_BIT) typedef struct { uint64_t optmask; diff --git a/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt b/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt deleted file mode 100644 index 2983268dac4da362d46348bc81d447e6d30252b7..0000000000000000000000000000000000000000 --- a/ldpctest_BG_1_Zc_384_rate_1-3_block_length_8448_maxit_5.txt +++ /dev/null @@ -1,64 +0,0 @@ -SNR BLER BER UNCODED_BER ENCODER_MEAN ENCODER_STD ENCODER_MAX DECODER_TIME_MEAN DECODER_TIME_STD DECODER_TIME_MAX DECODER_ITER_MEAN DECODER_ITER_STD DECODER_ITER_MAX --2.000000 1.000000 0.346185 0.258473 44.551218 31.688925 357.883903 217.655668 12.810778 326.852166 5.000000 0.000000 5 --1.900000 1.000000 0.345395 0.256275 40.787109 4.190954 65.926488 215.687102 4.300128 230.585721 5.000000 0.000000 5 --1.800000 1.000000 0.343100 0.253634 40.748628 3.912915 56.669470 215.314020 4.139156 227.806468 5.000000 0.000000 5 --1.700000 1.000000 0.341806 0.250634 40.550845 3.347808 56.032851 216.839001 5.959734 244.483352 5.000000 0.000000 5 --1.600000 1.000000 0.339245 0.248129 40.457158 3.735092 56.853508 215.747244 4.995522 242.867659 5.000000 0.000000 5 --1.500000 1.000000 0.337230 0.245763 41.178595 4.297429 56.265874 215.785600 4.151781 227.795995 5.000000 0.000000 5 --1.400000 1.000000 0.335131 0.243311 39.915221 2.739586 55.454917 216.866764 6.547848 251.528327 5.000000 0.000000 5 --1.300000 1.000000 0.333085 0.240664 40.119215 3.044973 55.978253 216.208443 4.459816 228.810686 5.000000 0.000000 5 --1.200000 1.000000 0.330664 0.238769 40.507713 2.998241 55.701876 215.868796 3.778455 226.049304 5.000000 0.000000 5 --1.100000 1.000000 0.329130 0.235812 41.038895 4.522472 56.760814 215.654663 4.746822 236.021980 5.000000 0.000000 5 --1.000000 1.000000 0.325980 0.233534 41.067622 4.626711 57.444142 215.260535 3.481966 225.512853 5.000000 0.000000 5 --0.900000 1.000000 0.323823 0.230863 40.683316 3.689159 56.208182 215.560917 5.180017 243.603452 5.000000 0.000000 5 --0.800000 1.000000 0.321004 0.228222 41.643513 4.717568 58.502452 215.630891 4.283475 238.574145 5.000000 0.000000 5 --0.700000 1.000000 0.317983 0.225520 41.214547 3.941824 56.054211 215.910346 4.375081 227.444626 5.000000 0.000000 5 --0.600000 1.000000 0.316243 0.222903 40.834442 4.370416 56.765508 215.153296 3.617927 226.280086 5.000000 0.000000 5 --0.500000 1.000000 0.312886 0.220473 40.178174 4.185502 64.657291 219.647151 4.454154 236.473446 5.000000 0.000000 5 --0.400000 1.000000 0.309757 0.217536 40.240385 3.172484 55.751563 217.761119 3.900779 228.757195 5.000000 0.000000 5 --0.300000 1.000000 0.305464 0.215229 40.852271 3.761739 56.158869 217.830497 4.087453 230.237764 5.000000 0.000000 5 --0.200000 1.000000 0.302919 0.212364 40.531166 3.688281 56.426841 217.657657 5.498697 253.516146 5.000000 0.000000 5 --0.100000 1.000000 0.298246 0.209310 41.058364 4.140510 59.959571 217.519279 4.087389 228.768313 5.000000 0.000000 5 -0.000000 1.000000 0.294110 0.207107 40.436486 3.604369 55.788895 217.853044 4.012624 236.118036 5.000000 0.000000 5 -0.100000 1.000000 0.288139 0.204033 40.603738 4.045866 57.560760 217.046816 4.583841 244.429411 5.000000 0.000000 5 -0.200000 1.000000 0.285604 0.201954 40.494607 3.886199 59.431970 217.322824 4.080988 233.317513 5.000000 0.000000 5 -0.300000 1.000000 0.278478 0.198929 40.311327 3.452837 56.124657 217.319394 4.434358 232.534720 5.000000 0.000000 5 -0.400000 1.000000 0.270992 0.196299 40.649243 3.415612 56.204178 218.079445 4.990947 245.055337 5.000000 0.000000 5 -0.500000 1.000000 0.263944 0.193661 40.464299 3.622703 56.602842 218.555364 3.936432 229.481159 5.000000 0.000000 5 -0.600000 1.000000 0.256340 0.191194 40.200314 2.474984 53.432412 216.547260 3.695211 227.198078 5.000000 0.000000 5 -0.700000 1.000000 0.251578 0.188606 40.111945 3.029821 54.900896 216.581752 4.247622 237.358365 5.000000 0.000000 5 -0.800000 1.000000 0.234558 0.184742 39.533282 1.182169 42.753097 215.462335 2.960246 226.716604 5.000000 0.000000 5 -0.900000 1.000000 0.225915 0.182691 39.851294 1.108193 42.180342 216.404194 4.450720 228.482353 5.000000 0.000000 5 -1.000000 1.000000 0.216180 0.179994 40.721936 3.302539 56.032206 217.082196 4.599188 227.979232 5.000000 0.000000 5 -1.100000 1.000000 0.203481 0.177332 41.006217 3.798207 56.014901 216.204345 4.292145 227.297386 5.000000 0.000000 5 -1.200000 1.000000 0.188297 0.174121 40.739289 3.269948 56.653507 216.585873 6.250858 251.207034 5.000000 0.000000 5 -1.300000 1.000000 0.172624 0.171622 41.215540 4.783342 55.692883 215.885639 3.629370 226.473280 5.000000 0.000000 5 -1.400000 1.000000 0.156483 0.169110 40.289903 3.749338 56.290861 215.663761 4.176366 225.824735 5.000000 0.000000 5 -1.500000 1.000000 0.136293 0.165692 42.208932 6.070189 69.182665 216.390504 4.816283 235.417446 5.000000 0.000000 5 -1.600000 1.000000 0.125127 0.163325 40.890581 3.941185 56.491504 215.752348 4.426511 226.425984 5.000000 0.000000 5 -1.700000 1.000000 0.104593 0.159971 41.263557 4.128935 57.062514 217.284932 5.311288 249.647163 5.000000 0.000000 5 -1.800000 1.000000 0.091397 0.157460 40.273078 3.062810 55.546913 217.252505 6.331426 251.175692 5.000000 0.000000 5 -1.900000 1.000000 0.078256 0.154628 40.407489 3.419342 56.316166 216.967648 4.712664 245.093313 5.000000 0.000000 5 -2.000000 1.000000 0.065221 0.152571 40.660365 4.317854 57.537407 216.198346 4.991856 245.173269 5.000000 0.000000 5 -2.100000 1.000000 0.053694 0.148885 40.355654 4.062614 60.051963 215.797667 4.447252 236.221454 5.000000 0.000000 5 -2.200000 1.000000 0.042182 0.146229 40.613562 4.124655 56.201536 216.117304 4.060825 227.115987 5.000000 0.000000 5 -2.300000 1.000000 0.034334 0.143612 40.465884 3.541452 55.067611 215.575953 4.891719 244.546802 5.000000 0.000000 5 -2.400000 1.000000 0.026641 0.140869 41.074690 4.697458 61.619188 216.069185 4.700827 233.830937 5.000000 0.000000 5 -2.500000 1.000000 0.019976 0.138112 40.766971 4.274128 58.871741 215.761570 5.633731 249.753931 5.000000 0.000000 5 -2.600000 1.000000 0.012826 0.135122 40.559343 2.952804 54.017706 215.835161 4.039993 226.822103 5.000000 0.000000 5 -2.700000 1.000000 0.010550 0.132915 40.985193 3.330639 55.013950 215.975836 4.240744 227.040703 5.000000 0.000000 5 -2.800000 1.000000 0.007327 0.130133 39.778804 3.002485 56.610555 216.462786 7.082268 265.051418 5.000000 0.000000 5 -2.900000 1.000000 0.004038 0.126763 40.327795 3.934211 55.515352 215.982666 4.626198 230.696124 5.000000 0.000000 5 -3.000000 1.000000 0.003087 0.124336 40.337807 3.537021 55.101627 215.468662 4.177203 230.789145 5.000000 0.000000 5 -3.100000 1.000000 0.001576 0.121689 39.812195 3.116738 55.422687 215.797778 4.091192 225.897780 5.000000 0.000000 5 -3.200000 0.980000 0.001000 0.118928 39.853764 2.871322 56.405555 215.562722 4.187466 232.598421 5.000000 0.000000 5 -3.300000 0.960000 0.000623 0.116065 40.440328 3.580650 56.738889 216.165848 4.735158 240.329999 5.000000 0.000000 5 -3.400000 0.850000 0.000303 0.113505 40.974107 4.291544 56.280236 215.889562 4.448049 237.556780 5.000000 0.000000 5 -3.500000 0.690000 0.000152 0.111010 41.508631 4.251791 56.198873 216.740295 4.889693 242.922934 5.000000 0.000000 5 -3.600000 0.530000 0.000102 0.108493 40.065231 3.643794 57.120823 216.887338 5.242621 250.003843 5.000000 0.000000 5 -3.700000 0.320000 0.000043 0.105612 40.462159 4.162383 56.782173 216.465615 3.846314 227.022697 5.000000 0.000000 5 -3.800000 0.210000 0.000032 0.103084 42.192455 6.207380 64.648964 217.030913 4.482820 228.095918 5.000000 0.000000 5 -3.900000 0.110000 0.000013 0.100391 40.640286 3.715782 55.922914 217.726055 4.553212 236.362804 5.000000 0.000000 5 -4.000000 0.050000 0.000006 0.097518 40.437760 2.838308 54.764308 218.230040 4.309275 237.932625 5.000000 0.000000 5 -4.100000 0.020000 0.000002 0.095436 41.347934 4.608500 64.182062 217.408836 4.385757 228.219627 5.000000 0.000000 5 -4.200000 0.000000 0.000000 0.092396 40.782371 3.621708 55.984245 217.579878 4.102149 228.145363 5.000000 0.000000 5 diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index d13dc5d1c50f0340fdb935961a624f1251778acf..8cc1bda7828bb3f1dfde92f7e862157906e6c9b8 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -217,7 +217,7 @@ void oai_create_enb(void) { } // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY - // that will result in eNB->configured being set to TRUE. + // that will result in eNB->configured being set to true. // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values if (RC.eNB[0][0]->if_inst==0 || RC.eNB[0][0]->if_inst->PHY_config_req==0 || RC.eNB[0][0]->if_inst->schedule_response==0) { NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.eNB[0][0]->if_inst->PHY_config_req is not installed - install it\n"); @@ -267,7 +267,7 @@ void oai_create_gnb(void) { // This will cause phy_config_request to be installed. That will result in RRC configuring the PHY - // that will result in gNB->configured being set to TRUE. + // that will result in gNB->configured being set to true. // See we need to wait for that to happen otherwise the NFAPI message exchanges won't contain the right parameter values if (RC.gNB[0]->if_inst==0 || RC.gNB[0]->if_inst->NR_PHY_config_req==0 || RC.gNB[0]->if_inst->NR_Schedule_response==0) { NFAPI_TRACE(NFAPI_TRACE_INFO, "RC.gNB[0][0]->if_inst->NR_PHY_config_req is not installed - install it\n"); diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h index ba66daa9c08783d287a3c60bac8ba72afc048286..6d40752a9aa5f3299105d96f5ebbad05f6645b9c 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h @@ -20,6 +20,7 @@ #define FAPI_NR_RX_PDU_TYPE_DLSCH 0x03 #define FAPI_NR_DCI_IND 0x04 #define FAPI_NR_RX_PDU_TYPE_RAR 0x05 +#define FAPI_NR_CSIRS_IND 0x06 #define FAPI_NR_SIBS_MASK_SIB1 0x1 diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index fd9af0172091531ad9451a51736f675df6a39f6d..a28762d1ff092d9fdb52e36e070172c40643d0ec 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -36,9 +36,6 @@ */ - - - typedef struct { uint8_t uci_format; uint8_t uci_channel; @@ -50,7 +47,14 @@ typedef struct { uint32_t sr; } fapi_nr_uci_pdu_rel15_t; - +typedef struct { + uint32_t rsrp; + int rsrp_dBm; + uint8_t rank_indicator; + uint8_t i1; + uint8_t i2; + uint8_t cqi; +} fapi_nr_csirs_measurements_t; typedef struct { /// frequency_domain_resource; @@ -87,7 +91,7 @@ typedef struct { // N_CCE is L, or number of CCEs for DCI int N_CCE; uint8_t payloadSize; - uint8_t payloadBits[16]; + uint8_t payloadBits[16] __attribute__((aligned(16))); // will be cast as uint64 //fapi_nr_dci_pdu_rel15_t dci; } fapi_nr_dci_indication_pdu_t; @@ -130,6 +134,7 @@ typedef struct { fapi_nr_pdsch_pdu_t pdsch_pdu; fapi_nr_ssb_pdu_t ssb_pdu; fapi_nr_sib_pdu_t sib_pdu; + fapi_nr_csirs_measurements_t csirs_measurements; }; } fapi_nr_rx_indication_body_t; diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index 8b564a5e3743be1a3ccf14ff2c53581eb7ceb11d..3a7dd8d523da6c5783fa090052a639b8a860b3b1 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -738,7 +738,7 @@ typedef struct { // The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BYTE_LEN*8 uint16_t PayloadSizeBits; // DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB - uint8_t Payload[DCI_PAYLOAD_BYTE_LEN]; + uint8_t Payload[DCI_PAYLOAD_BYTE_LEN] __attribute__((aligned(32))); } nfapi_nr_dl_dci_pdu_t; @@ -1666,41 +1666,34 @@ typedef struct } nfapi_nr_uci_indication_t; -//3.4.10 srs_indication -//table 3-73 -typedef struct -{ - uint8_t rb_snr; -}nfapi_nr_srs_indication_reported_symbol_resource_block_t; +/// 5G PHY FAPI Specification: SRS indication - Section 3.4.10, Table 3-73 -typedef struct -{ - uint16_t num_rbs; +typedef struct { + uint8_t rb_snr; // SNR value in dB. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB, 0xff will be set if this field is invalid. +} nfapi_nr_srs_indication_reported_symbol_resource_block_t; + +typedef struct { + uint16_t num_rbs; // Number of PRBs to be reported for this SRS PDU. Value: 0 -> 272. nfapi_nr_srs_indication_reported_symbol_resource_block_t* rb_list; -}nfapi_nr_srs_indication_reported_symbol_t; +} nfapi_nr_srs_indication_reported_symbol_t; -#define NFAPI_NR_SRS_IND_MAX_PDU 100 -typedef struct -{ - uint32_t handle; - uint16_t rnti; - uint16_t timing_advance; - uint8_t num_symbols; - uint8_t wide_band_snr; - uint8_t num_reported_symbols; +typedef struct { + uint32_t handle; // The handle passed to the PHY in the the UL_TTI.request SRS PDU. + uint16_t rnti; // The RNTI passed to the PHY in the UL_TTI.request SRS PDU. Value: 1 -> 65535. + uint16_t timing_advance; // Timing advance TA measured for the UE [TS 38.213, Section 4.2]. NTA_new = NTA_old + (TA − 31) * 16 * 64 / (2^u). Value: 0 -> 63. 0xffff should be set if this field is invalid. + uint8_t num_symbols; // Number of symbols for SRS. Value: 1 -> 4. If a PHY does not report for individual symbols then this parameter should be set to 1. + uint8_t wide_band_snr; // SNR value in dB measured within configured SRS bandwidth on each symbol. Value: 0 -> 255 representing -64 dB to 63 dB with a step size 0.5 dB. 0xff will be set if this field is invalid. + uint8_t num_reported_symbols; // Number of symbols reported in this message. This allows PHY to report individual symbols or aggregated symbols where this field will be set to 1. Value: 1 -> 4. nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list; +} nfapi_nr_srs_indication_pdu_t; -}nfapi_nr_srs_indication_pdu_t; - -typedef struct -{ +typedef struct { nfapi_p7_message_header_t header; - uint16_t sfn; - uint16_t slot; - uint8_t number_of_pdus; + uint16_t sfn; // SFN. Value: 0 -> 1023 + uint16_t slot; // Slot. Value: 0 -> 159 + uint8_t number_of_pdus; // Number of PDUs included in this message. Value: 0 -> 255 nfapi_nr_srs_indication_pdu_t* pdu_list; - } nfapi_nr_srs_indication_t; diff --git a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c index 264b25deca4520b0d7ea910c35d9b2b2da9e8cd6..af02a1605475b1600d97ecb20c791e57494307f3 100644 --- a/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c +++ b/openair1/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.c @@ -814,7 +814,7 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, llr_t *s1,*s2,*yp1,*yp2,*yp; unsigned int i,j,iind;//,pi; unsigned char iteration_cnt=0; - unsigned int crc,oldcrc,crc_len; + unsigned int crc, crc_len; uint8_t temp; #if defined(__x86_64__) || defined(__i386__) __m128i *yp128; @@ -1233,8 +1233,8 @@ uint8_t phy_threegpplte_turbo_decoder8(int16_t *y, } // check the CRC - oldcrc= *((unsigned int *)(&decoded_bytes[(n>>3)-crc_len])); - + uint32_t oldcrc; + memcpy(&oldcrc, &decoded_bytes[(n >> 3) - crc_len], crc_len); switch (crc_type) { case CRC24_A: oldcrc&=0x00ffffff; diff --git a/openair1/PHY/CODING/crc_byte.c b/openair1/PHY/CODING/crc_byte.c index 9ad18cc1a6336c5a542182813ea7f7b66a1c523e..471b26fe2434cffa82713a72b76d3515434bce2c 100644 --- a/openair1/PHY/CODING/crc_byte.c +++ b/openair1/PHY/CODING/crc_byte.c @@ -244,11 +244,11 @@ crc16 (unsigned char * inptr, int bitlen) while (octetlen-- > 0) { - crc = (crc << 8) ^ (crc16Table[(*inptr++) ^ (crc >> 24)] << 16); + crc = (crc << 8) ^ (((uint32_t)crc16Table[(*inptr++) ^ (crc >> 24)]) << 16); } if (resbit > 0) - crc = (crc << resbit) ^ (crc16Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 16); + crc = (crc << resbit) ^ (((uint32_t)crc16Table[(*inptr) >> (8 - resbit) ^ (crc >> (32 - resbit))]) << 16); return crc; } diff --git a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h index f4ea4a9434047e30d80f9c43371832adb5c47fed..f792f993e9c78066328ff859bb14afd9eaa69ca7 100644 --- a/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h +++ b/openair1/PHY/CODING/nrLDPC_decoder/nrLDPC_cnProc.h @@ -961,7 +961,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1028,7 +1029,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1096,7 +1098,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1163,7 +1166,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1230,7 +1234,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1297,7 +1302,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1364,7 +1370,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1431,7 +1438,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1498,7 +1506,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG1(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1593,7 +1602,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1660,7 +1670,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1727,7 +1738,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1794,7 +1806,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1861,7 +1874,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) @@ -1928,7 +1942,8 @@ static inline uint32_t nrLDPC_cnProcPc_BG2(t_nrLDPC_lut* p_lut, int8_t* cnProcBu // If no error pcRes should be 0 // Only use valid CNs - pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); + if (Mrem) + pcResSum |= (pcRes&(0xFFFFFFFF>>(32-Mrem))); // If PC failed we can stop here if (pcResSum > 0) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 76adf4d3146d19aeefd3b8c724fdea75a86f8e3a..4438bfca95dcc88a886b9e16135be49580b378ce 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -600,38 +600,23 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, // CSI RS init // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32) int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1; - gNB->nr_csi_rs_info = (nr_csi_rs_info_t *)malloc16_clear(sizeof(nr_csi_rs_info_t)); - gNB->nr_csi_rs_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **)); - AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs!=NULL, "NR init: csi reference signal malloc failed\n"); + gNB->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t)); + gNB->nr_csi_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame * sizeof(uint32_t **)); + AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n"); for (int slot=0; slot<fp->slots_per_frame; slot++) { - gNB->nr_csi_rs_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *)); - AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs[slot]!=NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot); + gNB->nr_csi_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot * sizeof(uint32_t *)); + AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs[slot] != NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot); for (int symb=0; symb<fp->symbols_per_slot; symb++) { - gNB->nr_csi_rs_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length*sizeof(uint32_t)); - AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); + gNB->nr_csi_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length * sizeof(uint32_t)); + AssertFatal(gNB->nr_csi_info->nr_gold_csi_rs[slot][symb] != NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); } } - gNB->nr_csi_rs_info->csi_gold_init = cfg->cell_config.phy_cell_id.value; - nr_init_csi_rs(&gNB->frame_parms, gNB->nr_csi_rs_info->nr_gold_csi_rs, cfg->cell_config.phy_cell_id.value); + gNB->nr_csi_info->csi_gold_init = cfg->cell_config.phy_cell_id.value; + nr_init_csi_rs(&gNB->frame_parms, gNB->nr_csi_info->nr_gold_csi_rs, cfg->cell_config.phy_cell_id.value); for (int id=0; id<NUMBER_OF_NR_SRS_MAX; id++) { gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); - gNB->nr_srs_info[id]->sc_list = (uint16_t *) malloc16_clear(6*fp->N_RB_UL*sizeof(uint16_t)); - gNB->nr_srs_info[id]->srs_generated_signal = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t)); - gNB->nr_srs_info[id]->srs_received_signal = (int32_t **)malloc16(Prx*sizeof(int32_t*)); - gNB->nr_srs_info[id]->srs_ls_estimated_channel = (int32_t **)malloc16(Prx*sizeof(int32_t*)); - gNB->nr_srs_info[id]->srs_estimated_channel_freq = (int32_t **)malloc16(Prx*sizeof(int32_t*)); - gNB->nr_srs_info[id]->srs_estimated_channel_time = (int32_t **)malloc16(Prx*sizeof(int32_t*)); - gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted = (int32_t **)malloc16(Prx*sizeof(int32_t*)); - for (i=0;i<Prx;i++){ - gNB->nr_srs_info[id]->srs_received_signal[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_ls_estimated_channel[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_estimated_channel_freq[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_estimated_channel_time[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted[i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - } } generate_ul_reference_signal_sequences(SHRT_MAX); @@ -779,31 +764,16 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB) } free_and_zero(pusch_dmrs); - uint32_t ***nr_gold_csi_rs = gNB->nr_csi_rs_info->nr_gold_csi_rs; + uint32_t ***nr_gold_csi_rs = gNB->nr_csi_info->nr_gold_csi_rs; for (int slot = 0; slot < fp->slots_per_frame; slot++) { for (int symb = 0; symb < fp->symbols_per_slot; symb++) free_and_zero(nr_gold_csi_rs[slot][symb]); free_and_zero(nr_gold_csi_rs[slot]); } free_and_zero(nr_gold_csi_rs); - free_and_zero(gNB->nr_csi_rs_info); + free_and_zero(gNB->nr_csi_info); for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) { - for (int i = 0; i < Prx; i++) { - free_and_zero(gNB->nr_srs_info[id]->srs_received_signal[i]); - free_and_zero(gNB->nr_srs_info[id]->srs_ls_estimated_channel[i]); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_freq[i]); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time[i]); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted[i]); - } - free_and_zero(gNB->nr_srs_info[id]->sc_list); - free_and_zero(gNB->nr_srs_info[id]->srs_generated_signal); - free_and_zero(gNB->nr_srs_info[id]->noise_power); - free_and_zero(gNB->nr_srs_info[id]->srs_received_signal); - free_and_zero(gNB->nr_srs_info[id]->srs_ls_estimated_channel); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_freq); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time); - free_and_zero(gNB->nr_srs_info[id]->srs_estimated_channel_time_shifted); free_and_zero(gNB->nr_srs_info[id]); } diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index c96aeab432477c356d5762cbd2e7d62f0d146383..75d78738fc6fa74f9d3e821087ea5479a43654ea 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -60,7 +60,7 @@ int nr_phy_init_RU(RU_t *ru) { for (i=0; i<ru->nb_tx; i++) { // Allocate 10 subframes of I/Q TX signal data (time) if not - ru->common.txdata[i] = (int32_t*)malloc16_clear((ru->sf_extension +fp->samples_per_frame) *sizeof(int32_t)); + ru->common.txdata[i] = (int32_t*)malloc16_clear((ru->sf_extension + fp->samples_per_frame)*sizeof(int32_t)); LOG_I(PHY,"[INIT] common.txdata[%d] = %p (%lu bytes,sf_extension %d)\n",i,ru->common.txdata[i], (ru->sf_extension + fp->samples_per_frame)*sizeof(int32_t),ru->sf_extension); ru->common.txdata[i] = &ru->common.txdata[i][ru->sf_extension]; diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index c6e6ecd46316d65564577ba8b0a7a23e6aabcede..3c1f8ac531ac5615339baedfffc851eb3ac57122 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -34,19 +34,6 @@ #include "PHY/NR_REFSIG/nr_refsig.h" #include "PHY/MODULATION/nr_modulation.h" -#if 0 -void phy_config_harq_ue(module_id_t Mod_id, - int CC_id, - uint8_t gNB_id, - uint16_t max_harq_tx) { - int num_of_threads,num_of_code_words; - PHY_VARS_NR_UE *phy_vars_ue = PHY_vars_UE_g[Mod_id][CC_id]; - - for (num_of_threads=0; num_of_threads<RX_NB_TH_MAX; num_of_threads++) - for (num_of_code_words=0; num_of_code_words<NR_MAX_NB_CODEWORDS; num_of_code_words++) - phy_vars_ue->ulsch[num_of_threads][gNB_id][num_of_code_words]->Mlimit = max_harq_tx; -} -#endif extern uint16_t beta_cqi[16]; @@ -159,7 +146,7 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) NR_UE_CSI_RS **const csirs_vars = ue->csirs_vars; NR_UE_SRS **const srs_vars = ue->srs_vars; - int i, j, slot, symb, gNB_id, th_id; + int i, slot, symb, gNB_id, th_id; LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx); @@ -347,52 +334,23 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32) int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1; - ue->nr_csi_rs_info = (nr_csi_rs_info_t *)malloc16_clear(sizeof(nr_csi_rs_info_t)); - ue->nr_csi_rs_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **)); - AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs!=NULL, "NR init: csi reference signal malloc failed\n"); + ue->nr_csi_info = (nr_csi_info_t *)malloc16_clear(sizeof(nr_csi_info_t)); + ue->nr_csi_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame * sizeof(uint32_t **)); + AssertFatal(ue->nr_csi_info->nr_gold_csi_rs != NULL, "NR init: csi reference signal malloc failed\n"); for (int slot=0; slot<fp->slots_per_frame; slot++) { - ue->nr_csi_rs_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *)); - AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs[slot]!=NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot); + ue->nr_csi_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot * sizeof(uint32_t *)); + AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot] != NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot); for (int symb=0; symb<fp->symbols_per_slot; symb++) { - ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length*sizeof(uint32_t)); - AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); + ue->nr_csi_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length * sizeof(uint32_t)); + AssertFatal(ue->nr_csi_info->nr_gold_csi_rs[slot][symb] != NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb); } } - ue->nr_csi_rs_info->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t)); - ue->nr_csi_rs_info->csi_rs_generated_signal = (int32_t **)malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *) ); + ue->nr_csi_info->csi_rs_generated_signal = (int32_t **)malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *) ); for (i=0; i<NR_MAX_NB_PORTS; i++) { - ue->nr_csi_rs_info->csi_rs_generated_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); - } - ue->nr_csi_rs_info->csi_rs_received_signal = (int32_t **)malloc16(fp->nb_antennas_rx * sizeof(int32_t *) ); - ue->nr_csi_rs_info->csi_rs_ls_estimated_channel = (int32_t ***)malloc16(fp->nb_antennas_rx * sizeof(int32_t **) ); - ue->nr_csi_rs_info->csi_rs_estimated_channel_freq = (int32_t ***)malloc16(fp->nb_antennas_rx * sizeof(int32_t **) ); - for (i=0; i<fp->nb_antennas_rx; i++) { - ue->nr_csi_rs_info->csi_rs_received_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); - ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i] = (int32_t **) malloc16_clear(NR_MAX_NB_PORTS * sizeof(int32_t *)); - ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i] = (int32_t **) malloc16_clear(NR_MAX_NB_PORTS * sizeof(int32_t *)); - for (j=0; j<NR_MAX_NB_PORTS; j++) { - ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i][j] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size * sizeof(int32_t)); - ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i][j] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size * sizeof(int32_t)); - } + ue->nr_csi_info->csi_rs_generated_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t)); } ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t)); - ue->nr_srs_info->sc_list = (uint16_t *) malloc16_clear(6*fp->N_RB_UL*sizeof(uint16_t)); - ue->nr_srs_info->srs_generated_signal = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) ); - ue->nr_srs_info->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t)); - ue->nr_srs_info->srs_received_signal = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_ls_estimated_channel = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_estimated_channel_freq = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_estimated_channel_time = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - ue->nr_srs_info->srs_estimated_channel_time_shifted = (int32_t **)malloc16( fp->nb_antennas_rx*sizeof(int32_t *) ); - for (i=0; i<fp->nb_antennas_rx; i++) { - ue->nr_srs_info->srs_received_signal[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_ls_estimated_channel[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_estimated_channel_freq[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_estimated_channel_time[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - ue->nr_srs_info->srs_estimated_channel_time_shifted[i] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size*MAX_NUM_NR_SRS_SYMBOLS*sizeof(int32_t)); - } - // RACH prach_vars[gNB_id]->prachF = (int16_t *)malloc16_clear( sizeof(int)*(7*2*sizeof(int)*(fp->ofdm_symbol_size*12)) ); @@ -486,55 +444,26 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB) free_and_zero(ue->pdsch_vars[th_id][gNB_id]); } } - + for (int gNB_id = 0; gNB_id < ue->n_connected_gNB; gNB_id++) { for (int th_id = 0; th_id < RX_NB_TH_MAX; th_id++) { - free_and_zero(ue->pdcch_vars[th_id][gNB_id]); } for (int i=0; i<NR_MAX_NB_PORTS; i++) { - free_and_zero(ue->nr_csi_rs_info->csi_rs_generated_signal[i]); - } - for (int i = 0; i < fp->nb_antennas_rx; i++) { - free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal[i]); - for (int j=0; j<NR_MAX_NB_PORTS; j++) { - free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i][j]); - free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i][j]); - } - free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i]); - free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i]); + free_and_zero(ue->nr_csi_info->csi_rs_generated_signal[i]); } + free_and_zero(ue->nr_csi_info->csi_rs_generated_signal); for (int slot=0; slot<fp->slots_per_frame; slot++) { for (int symb=0; symb<fp->symbols_per_slot; symb++) { - free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]); + free_and_zero(ue->nr_csi_info->nr_gold_csi_rs[slot][symb]); } - free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot]); + free_and_zero(ue->nr_csi_info->nr_gold_csi_rs[slot]); } - free_and_zero(ue->nr_csi_rs_info->noise_power); - free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs); - free_and_zero(ue->nr_csi_rs_info->csi_rs_generated_signal); - free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal); - free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel); - free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq); - free_and_zero(ue->nr_csi_rs_info); - - for (int i = 0; i < fp->nb_antennas_rx; i++) { - free_and_zero(ue->nr_srs_info->srs_received_signal[i]); - free_and_zero(ue->nr_srs_info->srs_ls_estimated_channel[i]); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_freq[i]); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_time[i]); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_time_shifted[i]); - } - free_and_zero(ue->nr_srs_info->sc_list); - free_and_zero(ue->nr_srs_info->srs_generated_signal); - free_and_zero(ue->nr_srs_info->noise_power); - free_and_zero(ue->nr_srs_info->srs_received_signal); - free_and_zero(ue->nr_srs_info->srs_ls_estimated_channel); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_freq); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_time); - free_and_zero(ue->nr_srs_info->srs_estimated_channel_time_shifted); + free_and_zero(ue->nr_csi_info->nr_gold_csi_rs); + free_and_zero(ue->nr_csi_info); + free_and_zero(ue->nr_srs_info); free_and_zero(ue->csiim_vars[gNB_id]); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index c867292942f840d3bffd2891769ddf9b0d4dc7ca..9327fe9fe89a255249794470e4160ec440732406 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -41,10 +41,10 @@ extern int16_t *ul_ref_sigs_rx[30][2][34]; int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, L1_rxtx_proc_t *proc, - LTE_eNB_ULSCH_t * ulsch, - int32_t **ul_ch_estimates, - int32_t **ul_ch_estimates_time, - int32_t **rxdataF_ext, + LTE_eNB_ULSCH_t * ulsch, + int32_t **ul_ch_estimates, + int32_t **ul_ch_estimates_time, + int32_t **rxdataF_ext, module_id_t UE_id, unsigned char l, unsigned char Ns) { @@ -88,7 +88,7 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, } uint16_t N_rb_alloc = ulsch->harq_processes[harq_pid]->nb_rb; - int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(16))); + int32_t tmp_estimates[N_rb_alloc*12] __attribute__((aligned(32))); Msc_RS = N_rb_alloc*12; cyclic_shift = (frame_parms->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift + ulsch->harq_processes[harq_pid]->n_DMRS2 + @@ -334,14 +334,14 @@ int32_t lte_ul_channel_estimation(LTE_DL_FRAME_PARMS *frame_parms, current_phase2 = cmin(abs(current_phase2),127); // msg("sym: %d, current_phase1: %d, ru: %d + j%d, current_phase2: %d, ru: %d + j%d\n",k,current_phase1,ru1[2*current_phase1],ru1[2*current_phase1+1],current_phase2,ru2[2*current_phase2],ru2[2*current_phase2+1]); // rotate channel estimates by estimated phase - rotate_cpx_vector((int16_t *) ul_ch1, - &ru1[2*current_phase1], - (int16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], + rotate_cpx_vector((c16_t *) ul_ch1, + (c16_t *)&ru1[2*current_phase1], + (c16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], Msc_RS, 15); - rotate_cpx_vector((int16_t *) ul_ch2, - &ru2[2*current_phase2], - (int16_t *) &tmp_estimates[0], + rotate_cpx_vector((c16_t *) ul_ch2, + (c16_t *)&ru2[2*current_phase2], + (c16_t *) tmp_estimates, Msc_RS, 15); // Combine the two rotated estimates @@ -657,14 +657,14 @@ int32_t lte_ul_channel_estimation_RRU(LTE_DL_FRAME_PARMS *frame_parms, current_phase2 = cmin(abs(current_phase2),127); // msg("sym: %d, current_phase1: %d, ru: %d + j%d, current_phase2: %d, ru: %d + j%d\n",k,current_phase1,ru1[2*current_phase1],ru1[2*current_phase1+1],current_phase2,ru2[2*current_phase2],ru2[2*current_phase2+1]); // rotate channel estimates by estimated phase - rotate_cpx_vector((int16_t *) ul_ch1, - &ru1[2*current_phase1], - (int16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], + rotate_cpx_vector((c16_t *) ul_ch1, + (c16_t *) &ru1[2*current_phase1], + (c16_t *) &ul_ch_estimates[aa][frame_parms->N_RB_UL*12*k], Msc_RS, 15); - rotate_cpx_vector((int16_t *) ul_ch2, - &ru2[2*current_phase2], - (int16_t *) &tmp_estimates[0], + rotate_cpx_vector((c16_t *) ul_ch2, + (c16_t *) &ru2[2*current_phase2], + (c16_t *) &tmp_estimates[0], Msc_RS, 15); // Combine the two rotated estimates diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index 1bbe9eb39a28159559597ae5008e4a623b5d7c68..dc73a56568edd39fc469c20fd642c604d15cd938 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -1997,7 +1997,7 @@ int get_narrowband_index(int N_RB_UL,int rb) { void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe) { uint8_t harq_pid; //uint8_t UE_id; - boolean_t new_ulsch = (find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST)==-1) ? TRUE : FALSE; + const bool new_ulsch = find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST) == -1; //AssertFatal((UE_id=find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0, // "No existing/free UE ULSCH for rnti %x\n",ulsch_pdu->ulsch_pdu_rel8.rnti); LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id]; @@ -2063,7 +2063,7 @@ void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu if ((ulsch->harq_processes[harq_pid]->status == SCH_IDLE) || (ulsch->harq_processes[harq_pid]->ndi != ulsch_pdu->ulsch_pdu_rel8.new_data_indication) || - (new_ulsch == TRUE)) { + (new_ulsch == true)) { ulsch->harq_processes[harq_pid]->status = ACTIVE; ulsch->harq_processes[harq_pid]->TBS = ulsch_pdu->ulsch_pdu_rel8.size<<3; ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks; diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c index 64e74ebfbf80341dd7d1b70d74240769b90858dd..0addfdf14c7fc0f267e05e7e8c0cd4493371983b 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools_common.c @@ -532,9 +532,12 @@ uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) { } +// FIXME: this function is compting PRB outside the range, so I FORCED in the range +// I can't understand the 3GPP spec, see below note uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { int offset; + int ret=-1; switch (N_RB_DL) { @@ -545,16 +548,16 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { switch (vrb) { case 0: // even: 0->0, 1->2, odd: 0->3, 1->5 case 1: - return ((3*odd_slot) + 2*(vrb&3))%6; + ret= ((3*odd_slot) + 2*(vrb&3))%6; break; case 2: // even: 2->3, 3->5, odd: 2->0, 3->2 case 3: - return ((3*odd_slot) + 2*(vrb&3) + 5)%6; + ret= ((3*odd_slot) + 2*(vrb&3) + 5)%6; break; case 4: // even: 4->1, odd: 4->4 - return ((3*odd_slot) + 1)%6; + ret= ((3*odd_slot) + 1)%6; case 5: // even: 5->4, odd: 5->1 - return ((3*odd_slot) + 4)%6; + ret= ((3*odd_slot) + 4)%6; break; } break; @@ -562,88 +565,90 @@ uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { case 15: if (vrb<12) { if ((vrb&3) < 2) // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11 - return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14); + ret= (((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14); else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13 - return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14); + ret= (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14); } if (vrb==12) - return (3+(7*odd_slot)) % 14; + ret= (3+(7*odd_slot)) % 14; if (vrb==13) - return (10+(7*odd_slot)) % 14; - return 14; + ret= (10+(7*odd_slot)) % 14; + ret= 14; break; + // Formula in TS 36.211, chap 6.2.3.2 + // Fix me: returns a PRB number > 24 when vrb is 24 case 25: - return (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24); + ret= (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24); break; case 50: // P=3 if (Ngap==0) { // Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27 if (vrb>=23) - offset=4; + offset=4; else - offset=0; + offset=0; if (vrb<44) { - if ((vrb&3)>=2) - return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46; - else - return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46; + if ((vrb&3)>=2) + ret= offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46; + else + ret= offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46; } if (vrb==44) // even: 44->11, odd: 45->34 - return offset+((23*odd_slot) + 22-12+1); + ret= offset+((23*odd_slot) + 22-12+1); if (vrb==45) // even: 45->10, odd: 45->33 - return offset+((23*odd_slot) + 22+12); + ret= offset+((23*odd_slot) + 22+12); if (vrb==46) - return offset+46+((23*odd_slot) + 23-12+1) % 46; + ret= offset+46+((23*odd_slot) + 23-12+1) % 46; if (vrb==47) - return offset+46+((23*odd_slot) + 23+12) % 46; + ret= offset+46+((23*odd_slot) + 23+12) % 46; if (vrb==48) - return offset+46+((23*odd_slot) + 23-12+1) % 46; + ret= offset+46+((23*odd_slot) + 23-12+1) % 46; if (vrb==49) - return offset+46+((23*odd_slot) + 23+12) % 46; + ret= offset+46+((23*odd_slot) + 23+12) % 46; } else { // Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27 if (vrb>=9) - offset=18; + offset=18; else - offset=0; + offset=0; if (vrb<12) { - if ((vrb&3)>=2) - return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18; - else - return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18; + if ((vrb&3)>=2) + ret= offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18; + else + ret= offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18; } else { - return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18); + ret= offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18); } } break; case 75: // Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0 if (Ngap ==0) { - return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64); + ret= ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64); } else { // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 - return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); + ret= ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); } break; case 100: // Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0 if (Ngap ==0) { - return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96); + ret= ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96); } else { // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 - return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); + ret= ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); } break; default: LOG_E(PHY,"Unknown N_RB_DL %d\n",N_RB_DL); - return 0; + ret= 0; } - return 0; + return ret%N_RB_DL; } @@ -677,7 +682,7 @@ void generate_RIV_tables(void) // printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs); localRIV2alloc_LUT6[RIV] = alloc0; - distRIV2alloc_even_LUT6[RIV] = allocdist0_0_even; + distRIV2alloc_even_LUT6[RIV] = allocdist0_0_even; distRIV2alloc_odd_LUT6[RIV] = allocdist0_0_odd; RIV2nb_rb_LUT6[RIV] = Lcrbs; RIV2first_rb_LUT6[RIV] = RBstart; @@ -693,15 +698,14 @@ void generate_RIV_tables(void) nVRB = Lcrbs-1+RBstart; //printf("RBstart %d, len %d --> ",RBstart,Lcrbs); alloc0 |= (1<<nVRB); - allocdist0_0_even |= (1<<get_prb(25,0,nVRB,0)); - allocdist0_0_odd |= (1<<get_prb(25,1,nVRB,0)); + allocdist0_0_even |= 1U << get_prb(25, 0, nVRB, 0); + allocdist0_0_odd |= 1U << get_prb(25, 1, nVRB, 0); //printf("alloc 0 %x, allocdist0_even %x, allocdist0_odd %x\n",alloc0,allocdist0_0_even,allocdist0_0_odd); RIV=computeRIV(25,RBstart,Lcrbs); if (RIV>RIV_max25) - RIV_max25 = RIV;; - + RIV_max25 = RIV; localRIV2alloc_LUT25[RIV] = alloc0; distRIV2alloc_even_LUT25[RIV] = allocdist0_0_even; @@ -730,37 +734,37 @@ void generate_RIV_tables(void) if (nVRB<32) - alloc0 |= (1<<nVRB); + alloc0 |= 1U << nVRB; else - alloc1 |= (1<<(nVRB-32)); + alloc1 |= 1U << (nVRB - 32); // Distributed Gap1, even slot nVRB_even_dist = get_prb(50,0,nVRB,0); if (nVRB_even_dist<32) - allocdist0_0_even |= (1<<nVRB_even_dist); + allocdist0_0_even |= 1U << nVRB_even_dist; else - allocdist1_0_even |= (1<<(nVRB_even_dist-32)); + allocdist1_0_even |= 1U << (nVRB_even_dist - 32); // Distributed Gap1, odd slot nVRB_odd_dist = get_prb(50,1,nVRB,0); if (nVRB_odd_dist<32) - allocdist0_0_odd |= (1<<nVRB_odd_dist); + allocdist0_0_odd |= (1U <<nVRB_odd_dist); else - allocdist1_0_odd |= (1<<(nVRB_odd_dist-32)); + allocdist1_0_odd |= (1U <<(nVRB_odd_dist-32)); // Distributed Gap2, even slot nVRB_even_dist = get_prb(50,0,nVRB,1); if (nVRB_even_dist<32) - allocdist0_1_even |= (1<<nVRB_even_dist); + allocdist0_1_even |= 1U << nVRB_even_dist; else - allocdist1_1_even |= (1<<(nVRB_even_dist-32)); + allocdist1_1_even |= 1U << (nVRB_even_dist - 32); // Distributed Gap2, odd slot nVRB_odd_dist = get_prb(50,1,nVRB,1); if (nVRB_odd_dist<32) - allocdist0_1_odd |= (1<<nVRB_odd_dist); + allocdist0_1_odd |= 1U << nVRB_odd_dist; else - allocdist1_1_odd |= (1<<(nVRB_odd_dist-32)); + allocdist1_1_odd |= 1U << (nVRB_odd_dist - 32); RIV=computeRIV(50,RBstart,Lcrbs); @@ -811,13 +815,13 @@ void generate_RIV_tables(void) nVRB = Lcrbs-1+RBstart; if (nVRB<32) - alloc0 |= (1<<nVRB); + alloc0 |= 1U << nVRB; else if (nVRB<64) - alloc1 |= (1<<(nVRB-32)); + alloc1 |= 1U << (nVRB - 32); else if (nVRB<96) - alloc2 |= (1<<(nVRB-64)); + alloc2 |= 1U << (nVRB - 64); else - alloc3 |= (1<<(nVRB-96)); + alloc3 |= 1U << (nVRB - 96); // Distributed Gap1, even slot nVRB_even_dist = get_prb(100,0,nVRB,0); @@ -825,15 +829,14 @@ void generate_RIV_tables(void) // if ((RBstart==0) && (Lcrbs<=8)) // printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist); - if (nVRB_even_dist<32) - allocdist0_0_even |= (1<<nVRB_even_dist); + allocdist0_0_even |= 1U << nVRB_even_dist; else if (nVRB_even_dist<64) - allocdist1_0_even |= (1<<(nVRB_even_dist-32)); + allocdist1_0_even |= 1U << (nVRB_even_dist - 32); else if (nVRB_even_dist<96) - allocdist2_0_even |= (1<<(nVRB_even_dist-64)); + allocdist2_0_even |= 1U << (nVRB_even_dist - 64); else - allocdist3_0_even |= (1<<(nVRB_even_dist-96)); + allocdist3_0_even |= 1U << (nVRB_even_dist - 96); /* if ((RBstart==0) && (Lcrbs<=8)) printf("rballoc =>(%08x.%08x.%08x.%08x)\n", allocdist0_0_even, @@ -845,38 +848,37 @@ void generate_RIV_tables(void) // Distributed Gap1, odd slot nVRB_odd_dist = get_prb(100,1,nVRB,0); if (nVRB_odd_dist<32) - allocdist0_0_odd |= (1<<nVRB_odd_dist); + allocdist0_0_odd |= 1U << nVRB_odd_dist; else if (nVRB_odd_dist<64) - allocdist1_0_odd |= (1<<(nVRB_odd_dist-32)); + allocdist1_0_odd |= 1U << (nVRB_odd_dist - 32); else if (nVRB_odd_dist<96) - allocdist2_0_odd |= (1<<(nVRB_odd_dist-64)); + allocdist2_0_odd |= 1U << (nVRB_odd_dist - 64); else - allocdist3_0_odd |= (1<<(nVRB_odd_dist-96)); + allocdist3_0_odd |= 1U << (nVRB_odd_dist - 96); // Distributed Gap2, even slot nVRB_even_dist = get_prb(100,0,nVRB,1); if (nVRB_even_dist<32) - allocdist0_1_even |= (1<<nVRB_even_dist); + allocdist0_1_even |= 1U << nVRB_even_dist; else if (nVRB_even_dist<64) - allocdist1_1_even |= (1<<(nVRB_even_dist-32)); + allocdist1_1_even |= 1U << (nVRB_even_dist - 32); else if (nVRB_even_dist<96) - allocdist2_1_even |= (1<<(nVRB_even_dist-64)); + allocdist2_1_even |= 1U << (nVRB_even_dist - 64); else - allocdist3_1_even |= (1<<(nVRB_even_dist-96)); + allocdist3_1_even |= 1U << (nVRB_even_dist - 96); // Distributed Gap2, odd slot nVRB_odd_dist = get_prb(100,1,nVRB,1); if (nVRB_odd_dist<32) - allocdist0_1_odd |= (1<<nVRB_odd_dist); + allocdist0_1_odd |= 1U << nVRB_odd_dist; else if (nVRB_odd_dist<64) - allocdist1_1_odd |= (1<<(nVRB_odd_dist-32)); + allocdist1_1_odd |= 1U << (nVRB_odd_dist - 32); else if (nVRB_odd_dist<96) - allocdist2_1_odd |= (1<<(nVRB_odd_dist-64)); + allocdist2_1_odd |= 1U << (nVRB_odd_dist - 64); else - allocdist3_1_odd |= (1<<(nVRB_odd_dist-96)); - + allocdist3_1_odd |= 1U << (nVRB_odd_dist - 96); RIV=computeRIV(100,RBstart,Lcrbs); diff --git a/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h b/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h index 3574ba67405c271fefe0a43d01936fb49010efd6..d90216c3e6ace8f32baae4ccf13de9d7d4ccd345 100644 --- a/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h +++ b/openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h @@ -509,7 +509,7 @@ typedef struct { /// Position of first CCE of the dci int firstCCE; /// flag to indicate that this is a RA response - boolean_t ra_flag; + bool ra_flag; /// rnti rnti_t rnti; /// Format diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 3ccbd8ca35ad7218ffccebfee25c00fd35816261..13109d8f5a19286d43644e2d30a63fdda4755575 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -288,7 +288,7 @@ static void TPencode(void * arg) { LTE_DL_eNB_HARQ_t *hadlsch=rdata->dlsch->harq_processes[harq_pid]; if ( rdata-> round == 0) { - uint8_t tmp[96+12+3+3*6144]; + uint8_t tmp[96+12+3+3*6144] __attribute__((aligned(32))); memset(tmp,LTE_NULL, TURBO_SIMD_SOFTBITS); start_meas(rdata->te_stats); encoder(rdata->input, diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c index 088e2c0a5e29665d2d64ba86e7a374906af00c52..b5e5b490a352c5c075475f1c24263b1dbf321ab2 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c @@ -64,6 +64,12 @@ extern uint16_t beta_cqi[16]; extern uint16_t beta_ri[16]; extern uint16_t beta_ack[16]; +static int errorRB(int rb, char * table, int line) { + LOG_E(PHY,"Received %d rb, impossble in table %s, at line %d\n", rb, table, line); + return 0; +} + +#define rbAllocCheck(RBalL, TabLe) (RBalL) > sizeof(TabLe)/sizeof(*TabLe) ? errorRB(RBalL, #TabLe, __LINE__) : TabLe[RBalL] void extract_dci1A_info(uint8_t N_RB_DL, frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) { uint8_t harq_pid=0; @@ -974,28 +980,28 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, { switch (N_RB_DL) { case 6: - NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; + NPRB = rbAllocCheck(rballoc, RIV2nb_rb_LUT6); if(rah) RIV_max = RIV_max6; else RIV_max = 0x3F; break; case 25: - NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; + NPRB = rbAllocCheck(rballoc,RIV2nb_rb_LUT25); if(rah) RIV_max = RIV_max25; else RIV_max = 0x1FFF; break; case 50: - NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; + NPRB = rbAllocCheck(rballoc,RIV2nb_rb_LUT50); if(rah) RIV_max = RIV_max50; else RIV_max = 0x1FFFF; break; case 100: - NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; + NPRB = rbAllocCheck(rballoc,RIV2nb_rb_LUT100); if(rah) RIV_max = RIV_max100; else @@ -1034,9 +1040,14 @@ int check_dci_format1_1a_coherency(DCI_format_t dci_format, // this is an eNB issue // retransmisison but old and new TBS are different !!! // work around, consider it as a new transmission - LOG_E(PHY,"Format1A Retransmission but TBS are different: consider it as new transmission !!! \n"); + LOG_E(PHY, + "Format1A Retransmission but TBS are different: consider it as new transmission !!!, round %d, mcs 1 %d, NPRB %d \n", + pdlsch0_harq->round, + mcs1, + NPRB); pdlsch0_harq->round = 0; //return(0); // ?? to cross check + return(0); // ?? to cross check } } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index 0b665737a7beb1ae27427d07a98a558a82874ed6..8f5e33d6e002467a8c13a3518d4bfafc554e7d2d 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -41,7 +41,7 @@ #include <stdlib.h> #include <string.h> #include <linux/version.h> -#if RHEL_RELEASE_CODE >= 1796 +#if defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403 #include <lapacke/lapacke_utils.h> #include <lapacke/lapacke.h> #else diff --git a/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c b/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c index 7d063e326effc919180e5ebe12c02fa19d85b6a2..83c74389cf2d0d92ea86a8db07fd5ae5b561637c 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/linear_preprocessing_rec.c @@ -14,7 +14,7 @@ data storage. */ #include <cblas.h> #include <string.h> #include <linux/version.h> -#if RHEL_RELEASE_CODE >= 1796 +#if defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403 #include <lapacke/lapacke_utils.h> #include <lapacke/lapacke.h> #else diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h index f5b8c6b64a0e287f90078bfbb407171ae6836705..36da4ccab0e8860d4ca875053faa38cfaf34b5cf 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h +++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h @@ -1272,14 +1272,6 @@ uint32_t get_TBS_DL(uint8_t mcs, uint16_t nb_rb); @return Transport block size */ uint32_t get_TBS_UL(uint8_t mcs, uint16_t nb_rb); -/* \brief Return bit-map of resource allocation for a given DCI rballoc (RIV format) and vrb type - @param N_RB_DL number of PRB on DL - @param indicator for even/odd slot - @param vrb vrb index - @param Ngap Gap indicator -*/ -uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap); - /* \brief Return prb for a given vrb index @param vrb_type VRB type (0=localized,1=distributed) @param rb_alloc_dci rballoc field from DCI diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h index b4ae44f6eab8b663a98de22b151338385c76bf33..5f8763414ef9ec6123d2fc52678267731704beb2 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h +++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_ue.h @@ -90,7 +90,7 @@ typedef struct { /// Redundancy-version of the current sub-frame uint8_t rvidx; /// Turbo-code outputs (36-212 V8.6 2009-03, p.12 - uint8_t d[MAX_NUM_ULSCH_SEGMENTS][(96+3+(3*6144))]; + uint8_t *d[MAX_NUM_ULSCH_SEGMENTS]; /// Sub-block interleaver outputs (36-212 V8.6 2009-03, p.16-17) uint8_t w[MAX_NUM_ULSCH_SEGMENTS][3*6144]; /// Number of code segments (for definition see 36-212 V8.6 2009-03, p.9) diff --git a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c index ae3ebbce9dc0ba96df89af0ba7875bf3e7880df8..c04ec160aa1b80356a74d52dd64fbada063b4270 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/ulsch_coding.c @@ -71,6 +71,7 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) { for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) { if (ulsch->harq_processes[i]->c[r]) { free16(ulsch->harq_processes[i]->c[r],((r==0)?8:0) + 3+768); + free16(ulsch->harq_processes[i]->d[r],0); ulsch->harq_processes[i]->c[r] = NULL; } } @@ -86,7 +87,7 @@ void free_ue_ulsch(LTE_UE_ULSCH_t *ulsch) { LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) { LTE_UE_ULSCH_t *ulsch; - unsigned char exit_flag = 0,i,j,r; + unsigned char exit_flag = 0; unsigned char bw_scaling =1; switch (N_RB_UL) { @@ -113,7 +114,7 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) { memset(ulsch,0,sizeof(LTE_UE_ULSCH_t)); ulsch->Mlimit = 4; - for (i=0; i<8; i++) { + for (int i=0; i<8; i++) { ulsch->harq_processes[i] = (LTE_UL_UE_HARQ_t *)malloc16(sizeof(LTE_UL_UE_HARQ_t)); // printf("ulsch->harq_processes[%d] %p\n",i,ulsch->harq_processes[i]); @@ -129,15 +130,11 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) { } if (abstraction_flag==0) { - for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) { - ulsch->harq_processes[i]->c[r] = (unsigned char *)malloc16(((r==0)?8:0) + 3+768); // account for filler in first segment and CRCs for multiple segment case - - if (ulsch->harq_processes[i]->c[r]) - memset(ulsch->harq_processes[i]->c[r],0,((r==0)?8:0) + 3+768); - else { - LOG_E(PHY,"Can't get c\n"); - exit_flag=2; - } + for (int r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) { + ulsch->harq_processes[i]->c[r] = malloc16_clear(((r==0)?8:0) + 3+768); // account for filler in first segment and CRCs for multiple segment case + AssertFatal(ulsch->harq_processes[i]->c[r], ""); + ulsch->harq_processes[i]->d[r] = malloc16_clear(96+3+(3*6144)); + AssertFatal(ulsch->harq_processes[i]->d[r], ""); } } @@ -148,15 +145,7 @@ LTE_UE_ULSCH_t *new_ue_ulsch(unsigned char N_RB_UL, uint8_t abstraction_flag) { exit_flag=3; } } - - if ((abstraction_flag == 0) && (exit_flag==0)) { - for (i=0; i<8; i++) - for (j=0; j<96; j++) - for (r=0; r<MAX_NUM_ULSCH_SEGMENTS; r++) - ulsch->harq_processes[i]->d[r][j] = LTE_NULL; - - return(ulsch); - } else if (abstraction_flag==1) + if (!exit_flag) return(ulsch); } @@ -191,7 +180,7 @@ uint32_t ulsch_encoding(uint8_t *a, uint32_t Qprime_ACK=0,Qprime_CQI=0,Qprime_RI=0,len_ACK=0,len_RI=0; // uint32_t E; uint8_t ack_parity; - uint32_t i,q,j,iprime,j2; + uint32_t q,j,iprime,j2; uint16_t o_RCC; uint8_t o_flip[8]; uint32_t wACK_idx; @@ -327,6 +316,8 @@ uint32_t ulsch_encoding(uint8_t *a, #endif // offset=0; start_meas(te_stats); + for (int z=0; z<96; z++) + ulsch->harq_processes[harq_pid]->d[r][z] = LTE_NULL; encoder(ulsch->harq_processes[harq_pid]->c[r], Kr>>3, &ulsch->harq_processes[harq_pid]->d[r][96], @@ -539,8 +530,6 @@ uint32_t ulsch_encoding(uint8_t *a, ulsch->q); } - i=0; - // Do RI coding if (ulsch->O_RI == 1) { switch (Q_m) { @@ -691,7 +680,7 @@ uint32_t ulsch_encoding(uint8_t *a, j=0; - for (i=0; i<Qprime_RI; i++) { + for (int i=0; i<Qprime_RI; i++) { r = Rmux_prime - 1 - (i>>2); for (q=0; q<Q_m; q++) { @@ -725,7 +714,7 @@ uint32_t ulsch_encoding(uint8_t *a, } */ - for (i=0; i<Qprime_CQI; i++) { + for (int i=0; i<Qprime_CQI; i++) { while (y[Q_m*j] != LTE_NULL) j++; for (q=0; q<Q_m; q++) { @@ -788,7 +777,7 @@ uint32_t ulsch_encoding(uint8_t *a, j=0; - for (i=0; i<Qprime_ACK; i++) { + for (int i=0; i<Qprime_ACK; i++) { r = Rmux_prime - 1 - (i>>2); for (q=0; q<Q_m; q++) { @@ -808,7 +797,7 @@ uint32_t ulsch_encoding(uint8_t *a, switch (Q_m) { case 2: - for (i=0; i<Cmux; i++) + for (int i=0; i<Cmux; i++) for (r=0; r<Rmux_prime; r++) { yptr=&y[((r*Cmux)+i)<<1]; ulsch->h[j++] = *yptr++; @@ -818,7 +807,7 @@ uint32_t ulsch_encoding(uint8_t *a, break; case 4: - for (i=0; i<Cmux; i++) + for (int i=0; i<Cmux; i++) for (r=0; r<Rmux_prime; r++) { yptr = &y[((r*Cmux)+i)<<2]; ulsch->h[j++] = *yptr++; @@ -830,7 +819,7 @@ uint32_t ulsch_encoding(uint8_t *a, break; case 6: - for (i=0; i<Cmux; i++) + for (int i=0; i<Cmux; i++) for (r=0; r<Rmux_prime; r++) { yptr = &y[((r*Cmux)+i)*6]; ulsch->h[j++] = *yptr++; diff --git a/openair1/PHY/MODULATION/nr_modulation.c b/openair1/PHY/MODULATION/nr_modulation.c index 8352a7f5a64a00bb45a2abb8a0e0a7b21b0f6159..979a31c50462f3aa51790f11097c1f85938b483f 100644 --- a/openair1/PHY/MODULATION/nr_modulation.c +++ b/openair1/PHY/MODULATION/nr_modulation.c @@ -226,10 +226,11 @@ void nr_modulation(uint32_t *in, i *= 24; bit_cnt = i * 8; while (bit_cnt < length) { - x = *((uint32_t*)(in_bytes+i)); - x1 = x&4095; + uint32_t xx; + memcpy(&xx, in_bytes+i, sizeof(xx)); + x1 = xx & 4095; out64[j++] = nr_64qam_mod_table[x1]; - x1 = (x>>12)&4095; + x1 = (xx >> 12) & 4095; out64[j++] = nr_64qam_mod_table[x1]; i += 3; bit_cnt += 24; @@ -617,47 +618,38 @@ void init_symbol_rotation(NR_DL_FRAME_PARMS *fp) { for (uint8_t ll = 0; ll < 2; ll++){ double f0 = f[ll]; - double Ncpm1 = Ncp0; - int16_t *symbol_rotation = fp->symbol_rotation[ll]; - - double tl = 0; - double poff = 2 * M_PI * ((Ncp0 * Tc)) * f0; - double exp_re = cos(poff); - double exp_im = sin(-poff); - symbol_rotation[0] = (int16_t)floor(exp_re * 32767); - symbol_rotation[1] = (int16_t)floor(exp_im * 32767); LOG_I(PHY, "Doing symbol rotation calculation for gNB TX/RX, f0 %f Hz, Nsymb %d\n", f0, nsymb); - LOG_I(PHY, "Symbol rotation %d/%d => (%d,%d)\n", - 0, - nsymb, - symbol_rotation[0], - symbol_rotation[1]); + c16_t *symbol_rotation = fp->symbol_rotation[ll]; + + double tl = 0.0; + double poff = 0.0; + double exp_re = 0.0; + double exp_im = 0.0; - for (int l = 1; l < nsymb; l++) { + for (int l = 0; l < nsymb; l++) { double Ncp; - if (l == (7 * (1 << fp->numerology_index))) { + if (l == 0 || l == (7 * (1 << fp->numerology_index))) { Ncp = Ncp0; } else { Ncp = Ncp1; } - tl += (Nu + Ncpm1) * Tc; poff = 2 * M_PI * (tl + (Ncp * Tc)) * f0; exp_re = cos(poff); exp_im = sin(-poff); - symbol_rotation[l<<1] = (int16_t)floor(exp_re * 32767); - symbol_rotation[1 + (l<<1)] = (int16_t)floor(exp_im * 32767); + symbol_rotation[l].r = (int16_t)floor(exp_re * 32767); + symbol_rotation[l].i = (int16_t)floor(exp_im * 32767); LOG_I(PHY, "Symbol rotation %d/%d => tl %f (%d,%d) (%f)\n", l, nsymb, tl, - symbol_rotation[l<<1], - symbol_rotation[1 + (l<<1)], + symbol_rotation[l].r, + symbol_rotation[l].i, (poff / 2 / M_PI) - floor(poff / 2 / M_PI)); - Ncpm1 = Ncp; + tl += (Nu + Ncp) * Tc; } } @@ -670,13 +662,13 @@ void init_timeshift_rotation(NR_DL_FRAME_PARMS *fp) double poff = -i * 2.0 * M_PI * sample_offset / fp->ofdm_symbol_size; double exp_re = cos(poff); double exp_im = sin(-poff); - fp->timeshift_symbol_rotation[i*2] = (int16_t)round(exp_re * 32767); - fp->timeshift_symbol_rotation[i*2+1] = (int16_t)round(exp_im * 32767); + fp->timeshift_symbol_rotation[i].r = (int16_t)round(exp_re * 32767); + fp->timeshift_symbol_rotation[i].i = (int16_t)round(exp_im * 32767); if (i < 10) LOG_I(PHY,"Timeshift symbol rotation %d => (%d,%d) %f\n",i, - fp->timeshift_symbol_rotation[i*2], - fp->timeshift_symbol_rotation[i*2+1], + fp->timeshift_symbol_rotation[i].r, + fp->timeshift_symbol_rotation[i].i, poff); } } diff --git a/openair1/PHY/MODULATION/ofdm_mod.c b/openair1/PHY/MODULATION/ofdm_mod.c index 2f075e8218d7da918b8826a6167014aef7e93d95..0b8f22a0943ef920fd4a37f2951cfa312f84bbdf 100644 --- a/openair1/PHY/MODULATION/ofdm_mod.c +++ b/openair1/PHY/MODULATION/ofdm_mod.c @@ -46,18 +46,18 @@ void normal_prefix_mod(int32_t *txdataF,int32_t *txdata,uint8_t nsymb,LTE_DL_FRA PHY_ofdm_mod(txdataF, // input - txdata, // output - frame_parms->ofdm_symbol_size, + txdata, // output + frame_parms->ofdm_symbol_size, - 1, // number of symbols - frame_parms->nb_prefix_samples0, // number of prefix samples - CYCLIC_PREFIX); + 1, // number of symbols + frame_parms->nb_prefix_samples0, // number of prefix samples + CYCLIC_PREFIX); PHY_ofdm_mod(txdataF+frame_parms->ofdm_symbol_size, // input - txdata+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0, // output - frame_parms->ofdm_symbol_size, - nsymb-1, - frame_parms->nb_prefix_samples, // number of prefix samples - CYCLIC_PREFIX); + txdata+OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES0, // output + frame_parms->ofdm_symbol_size, + nsymb-1, + frame_parms->nb_prefix_samples, // number of prefix samples + CYCLIC_PREFIX); @@ -341,14 +341,14 @@ void do_OFDM_mod(int32_t **txdataF, int32_t **txdata, uint32_t frame,uint16_t ne } void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, - int16_t* trxdata, - int slot, - int first_symbol, - int nsymb, - int length) { + int16_t* trxdata, + int slot, + int first_symbol, + int nsymb, + int length) { int symb_offset = (slot%fp->slots_per_subframe)*fp->symbols_per_slot; - int16_t *symbol_rotation = fp->symbol_rotation[0]; + c16_t *symbol_rotation = fp->symbol_rotation[0]; for (int sidx=0;sidx<nsymb;sidx++) { @@ -357,14 +357,14 @@ void apply_nr_rotation(NR_DL_FRAME_PARMS *fp, slot, sidx + first_symbol + symb_offset, length, - symbol_rotation[2 * (sidx + first_symbol + symb_offset)], - symbol_rotation[1 + 2 * (sidx + first_symbol + symb_offset)]); + symbol_rotation[sidx + first_symbol + symb_offset].r, + symbol_rotation[sidx + first_symbol + symb_offset].i); - rotate_cpx_vector(trxdata + (sidx * length * 2), - &symbol_rotation[2 * (sidx + first_symbol + symb_offset)], - trxdata + (sidx * length * 2), + rotate_cpx_vector(((c16_t*) trxdata) + sidx * length, + symbol_rotation + sidx + first_symbol + symb_offset, + ((c16_t*) trxdata) + sidx * length, length, 15); } } - + diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index 139b730ce1bb515046340fef8fc6394d5c22451a..548db21878e5fb870ab547d62f1c148db456666c 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -98,25 +98,25 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, stop_meas(&ue->rx_dft_stats); int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol+symb_offset]; - ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; + c16_t rot2 = frame_parms->symbol_rotation[0][symbol+symb_offset]; + rot2.i=-rot2.i; #ifdef DEBUG_FEP // if (ue->frame <100) printf("slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset, - symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); + symbol+symb_offset,rot2.r,rot2.i); #endif - rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], - (int16_t*)&rot2, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + rotate_cpx_vector((c16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + &rot2, + (c16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], frame_parms->ofdm_symbol_size, 15); - int16_t *shift_rot = frame_parms->timeshift_symbol_rotation; + c16_t *shift_rot = frame_parms->timeshift_symbol_rotation; multadd_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], - shift_rot, + (int16_t *)shift_rot, (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], 1, frame_parms->ofdm_symbol_size, @@ -214,18 +214,18 @@ int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, stop_meas(&ue->rx_dft_stats); int symb_offset = (Ns%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; - int32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[0])[symbol + symb_offset]; - ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; + c16_t rot2 = frame_parms->symbol_rotation[0][symbol + symb_offset]; + rot2.i=-rot2.i; #ifdef DEBUG_FEP // if (ue->frame <100) printf("slot_fep: slot %d, symbol %d rx_offset %u, rotation symbol %d %d.%d\n", Ns,symbol, rx_offset, - symbol+symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); + symbol+symb_offset,rot2.r,rot2.i); #endif - rotate_cpx_vector((int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], - (int16_t*)&rot2, - (int16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + rotate_cpx_vector((c16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], + &rot2, + (c16_t *)&common_vars->common_vars_rx_data_per_thread[proc->thread_id].rxdataF[aa][frame_parms->ofdm_symbol_size*symbol], frame_parms->ofdm_symbol_size, 15); } @@ -310,19 +310,19 @@ void apply_nr_rotation_ul(NR_DL_FRAME_PARMS *frame_parms, for (int symbol=first_symbol;symbol<nsymb;symbol++) { - uint32_t rot2 = ((uint32_t*)frame_parms->symbol_rotation[1])[symbol + symb_offset]; - ((int16_t*)&rot2)[1]=-((int16_t*)&rot2)[1]; - LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,((int16_t*)&rot2)[0],((int16_t*)&rot2)[1]); - rotate_cpx_vector((int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], - (int16_t*)&rot2, - (int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], + c16_t rot2 = frame_parms->symbol_rotation[1][symbol + symb_offset]; + rot2.i=-rot2.i; + LOG_D(PHY,"slot %d, symb_offset %d rotating by %d.%d\n",slot,symb_offset,rot2.r,rot2.i); + rotate_cpx_vector((c16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], + &rot2, + (c16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], length, 15); - int16_t *shift_rot = frame_parms->timeshift_symbol_rotation; + c16_t *shift_rot = frame_parms->timeshift_symbol_rotation; multadd_cpx_vector((int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], - shift_rot, + (int16_t *)shift_rot, (int16_t *)&rxdataF[soffset+(frame_parms->ofdm_symbol_size*symbol)], 1, length, diff --git a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c index fb56322e5440a89705f57faff5b96bb8b30aa29c..c527c3fc9df083c115f095d1d655e1c35a81c98f 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c +++ b/openair1/PHY/NR_ESTIMATION/nr_measurements_gNB.c @@ -67,6 +67,49 @@ int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id) return max_pos - sync_pos; } +int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, + const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]) { + int timing_advance = 0; + int max_val = 0; + + for (int i = 0; i < frame_parms->ofdm_symbol_size; i++) { + int temp = 0; + for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + int Re = ((c16_t*)srs_estimated_channel_time[aa])[i].r; + int Im = ((c16_t*)srs_estimated_channel_time[aa])[i].i; + temp += (Re*Re/2) + (Im*Im/2); + } + if (temp > max_val) { + timing_advance = i; + max_val = temp; + } + } + + if (timing_advance > frame_parms->ofdm_symbol_size/2) { + timing_advance = timing_advance - frame_parms->ofdm_symbol_size; + } + + // Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size + const uint16_t bw_scaling = frame_parms->ofdm_symbol_size >> 7; + + // do some integer rounding to improve TA accuracy + int sync_pos_rounded; + if (timing_advance > 0) { + sync_pos_rounded = timing_advance + (bw_scaling >> 1) - 1; + } else { + sync_pos_rounded = timing_advance - (bw_scaling >> 1) + 1; + } + + int timing_advance_update = sync_pos_rounded / bw_scaling; + + // put timing advance command in 0..63 range + timing_advance_update += 31; + + if (timing_advance_update < 0) timing_advance_update = 0; + if (timing_advance_update > 63) timing_advance_update = 63; + + return timing_advance_update; +} void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) { @@ -108,9 +151,9 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb NR_gNB_COMMON *common_vars = &gNB->common_vars; PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements; int rb, nb_symb[275]={0}; - + memset(measurements->n0_subband_power, 0, sizeof(measurements->n0_subband_power)); - + for (int s=first_symb;s<(first_symb+num_symb);s++) { for (rb=0; rb<frame_parms->N_RB_UL; rb++) { if (s==first_symb /*&& ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0)*/) { @@ -119,13 +162,13 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB,int slot, int first_symb,int num_symb measurements->n0_subband_power[aarx][rb]=0; } int offset0 = (slot&3)*(frame_parms->symbols_per_slot * frame_parms->ofdm_symbol_size) + (frame_parms->first_carrier_offset + (rb*12))%frame_parms->ofdm_symbol_size; - if ((gNB->rb_mask_ul[s][rb>>5]&(1<<(rb&31))) == 0) { // check that rb was not used in this subframe + if ((gNB->rb_mask_ul[s][rb >> 5] & (1U << (rb & 31))) == 0) { // check that rb was not used in this subframe nb_symb[rb]++; for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { int offset = offset0 + (s*frame_parms->ofdm_symbol_size); int32_t *ul_ch = &common_vars->rxdataF[aarx][offset]; int len = 12; - if (((frame_parms->N_RB_UL&1) == 1) && + if (((frame_parms->N_RB_UL&1) == 1) && (rb==(frame_parms->N_RB_UL>>1))) { len=6; } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index cd3b535b3fd8024b1a3040bd1d1ecd53823bb446..e5c1ca37d820494cbefc37f61e2e9418d348b433 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -854,7 +854,6 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, uint32_t nb_re_pusch) { //#define DEBUG_UL_PTRS 1 - int16_t *phase_per_symbol = NULL; int32_t *ptrs_re_symbol = NULL; int8_t ret = 0; @@ -871,20 +870,20 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, uint8_t *ptrsReOffset = &rel15_ul->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset; /* loop over antennas */ for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - phase_per_symbol = (int16_t*)gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx]; + c16_t *phase_per_symbol = (c16_t*)gNB->pusch_vars[ulsch_id]->ptrs_phase_per_slot[aarx]; ptrs_re_symbol = &gNB->pusch_vars[ulsch_id]->ptrs_re_per_slot; *ptrs_re_symbol = 0; - phase_per_symbol[(2*symbol)+1] = 0; // Imag + phase_per_symbol[symbol].i = 0; /* set DMRS estimates to 0 angle with magnitude 1 */ if(is_dmrs_symbol(symbol,*dmrsSymbPos)) { /* set DMRS real estimation to 32767 */ - phase_per_symbol[2*symbol]=(int16_t)((1<<15)-1); // 32767 + phase_per_symbol[symbol].r=INT16_MAX; // 32767 #ifdef DEBUG_UL_PTRS - printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[2*symbol],phase_per_symbol[(2*symbol)+1]); + printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[symbol].r,phase_per_symbol[symbol].i); #endif } else {// real ptrs value is set to 0 - phase_per_symbol[2*symbol] = 0; // Real + phase_per_symbol[symbol].r = 0; } if(symbol == *startSymbIndex) { @@ -909,7 +908,7 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, symbol,frame_parms->ofdm_symbol_size, (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(symbol * nb_re_pusch)], gNB->nr_gold_pusch_dmrs[rel15_ul->scid][nr_tti_rx][symbol], - &phase_per_symbol[2* symbol], + (int16_t*)&phase_per_symbol[symbol], ptrs_re_symbol); } /* For last OFDM symbol at each antenna perform interpolation and compensation for the slot*/ @@ -919,7 +918,7 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, /*------------------------------------------------------------------------------------------------------- */ /* If L-PTRS is > 0 then we need interpolation */ if(*L_ptrs > 0) { - ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, phase_per_symbol, *startSymbIndex, *nbSymb); + ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, (int16_t*)phase_per_symbol, *startSymbIndex, *nbSymb); if(ret != 0) { LOG_W(PHY,"[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n"); } @@ -938,11 +937,11 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, /* Skip rotation if the slot processing is wrong */ if((!is_dmrs_symbol(i,*dmrsSymbPos)) && (ret == 0)) { #ifdef DEBUG_UL_PTRS - printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]); + printf("[PHY][UL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i); #endif - rotate_cpx_vector((int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], - &phase_per_symbol[2* i], - (int16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], + rotate_cpx_vector((c16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], + &phase_per_symbol[i], + (c16_t*)&gNB->pusch_vars[ulsch_id]->rxdataF_comp[aarx][(i * rel15_ul->rb_size * NR_NB_SC_PER_RB)], ((*nb_rb) * NR_NB_SC_PER_RB), 15); }// if not DMRS Symbol }// symbol loop @@ -950,9 +949,9 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, }//Antenna loop } -uint32_t calc_power(uint16_t *x, uint32_t size) { - uint64_t sum_x = 0; - uint64_t sum_x2 = 0; +uint32_t calc_power(const int16_t *x, const uint32_t size) { + int64_t sum_x = 0; + int64_t sum_x2 = 0; for(int k = 0; k<size; k++) { sum_x = sum_x + x[k]; sum_x2 = sum_x2 + x[k]*x[k]; @@ -960,28 +959,34 @@ uint32_t calc_power(uint16_t *x, uint32_t size) { return sum_x2/size - (sum_x/size)*(sum_x/size); } -int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, - int frame, - int slot, - nfapi_nr_srs_pdu_t *srs_pdu, - nr_srs_info_t *nr_srs_info, - int32_t *srs_generated_signal, - int32_t **srs_received_signal, - int32_t **srs_estimated_channel_freq, - int32_t **srs_estimated_channel_time, - int32_t **srs_estimated_channel_time_shifted, - uint32_t *noise_power) { +int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, + const int frame, + const int slot, + const nfapi_nr_srs_pdu_t *srs_pdu, + const nr_srs_info_t *nr_srs_info, + const int32_t *srs_generated_signal, + int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)], + int32_t srs_ls_estimated_channel[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)], + int32_t srs_estimated_channel_freq[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)], + int32_t srs_estimated_channel_time[][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_estimated_channel_time_shifted[][gNB->frame_parms.ofdm_symbol_size], + uint32_t *signal_power, + uint32_t *noise_power_per_rb, + uint32_t *noise_power, + int8_t *snr_per_rb, + int8_t *snr) { if(nr_srs_info->sc_list_length == 0) { LOG_E(NR_PHY, "(%d.%d) nr_srs_info was not generated yet!\n", frame, slot); return -1; } - NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - int32_t **srs_ls_estimated_channel = nr_srs_info->srs_ls_estimated_channel; + const NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; - uint16_t noise_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; - uint16_t noise_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t ch_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t ch_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t noise_real[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; + int16_t noise_imag[frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length]; int16_t ls_estimated[2]; @@ -994,11 +999,11 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { - int16_t generated_real = srs_generated_signal[nr_srs_info->sc_list[sc_idx]] & 0xFFFF; - int16_t generated_imag = (srs_generated_signal[nr_srs_info->sc_list[sc_idx]] >> 16) & 0xFFFF; + int16_t generated_real = ((c16_t*)srs_generated_signal)[nr_srs_info->sc_list[sc_idx]].r; + int16_t generated_imag = ((c16_t*)srs_generated_signal)[nr_srs_info->sc_list[sc_idx]].i; - int16_t received_real = srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]] & 0xFFFF; - int16_t received_imag = (srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]] >> 16) & 0xFFFF; + int16_t received_real = ((c16_t*)srs_received_signal[ant])[nr_srs_info->sc_list[sc_idx]].r; + int16_t received_imag = ((c16_t*)srs_received_signal[ant])[nr_srs_info->sc_list[sc_idx]].i; // We know that nr_srs_info->srs_generated_signal_bits bits are enough to represent the generated_real and generated_imag. // So we only need a nr_srs_info->srs_generated_signal_bits shift to ensure that the result fits into 16 bits. @@ -1069,8 +1074,10 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, // Compute noise for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { - noise_real[ant*nr_srs_info->sc_list_length + sc_idx] = abs((int16_t)((srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]]-srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]]) & 0xFFFF)); - noise_imag[ant*nr_srs_info->sc_list_length + sc_idx] = abs((int16_t)(((srs_ls_estimated_channel[ant][nr_srs_info->sc_list[sc_idx]]-srs_estimated_channel_freq[ant][nr_srs_info->sc_list[sc_idx]]) >> 16) & 0xFFFF)); + ch_real[ant*nr_srs_info->sc_list_length + sc_idx] = ((c16_t*)srs_estimated_channel_freq[ant])[nr_srs_info->sc_list[sc_idx]].r; + ch_imag[ant*nr_srs_info->sc_list_length + sc_idx] = ((c16_t*)srs_estimated_channel_freq[ant])[nr_srs_info->sc_list[sc_idx]].i; + noise_real[ant*nr_srs_info->sc_list_length + sc_idx] = abs(((c16_t*)srs_ls_estimated_channel[ant])[nr_srs_info->sc_list[sc_idx]].r - ch_real[ant*nr_srs_info->sc_list_length + sc_idx]); + noise_imag[ant*nr_srs_info->sc_list_length + sc_idx] = abs(((c16_t*)srs_ls_estimated_channel[ant])[nr_srs_info->sc_list[sc_idx]].i - ch_imag[ant*nr_srs_info->sc_list_length + sc_idx]); } // Convert to time domain @@ -1087,11 +1094,74 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, (gNB->frame_parms.ofdm_symbol_size>>1)*sizeof(int32_t)); } + // Compute signal power + *signal_power = calc_power(ch_real,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length) + + calc_power(ch_imag,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length); + +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"signal_power = %u\n", *signal_power); +#endif + + if (*signal_power == 0) { + LOG_W(NR_PHY, "Received SRS signal power is 0\n"); + return -1; + } + + // Compute noise power + + const uint8_t signal_power_bits = log2_approx(*signal_power); + const uint8_t factor_bits = signal_power_bits < 32 ? 32 - signal_power_bits : 0; // 32 due to input of dB_fixed(uint32_t x) + const int32_t factor_dB = dB_fixed(1<<factor_bits); + + const uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12; + const uint8_t srs_symbols_per_rb = srs_pdu->comb_size == 0 ? 6 : 3; + const uint8_t n_noise_est = frame_parms->nb_antennas_rx * srs_symbols_per_rb; + uint8_t count_estimates = 0; + uint64_t sum_re = 0; + uint64_t sum_re2 = 0; + uint64_t sum_im = 0; + uint64_t sum_im2 = 0; + + for (int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { + + int subcarrier0 = nr_srs_info->sc_list[sc_idx]-subcarrier_offset; + if(subcarrier0 < 0) { + subcarrier0 = subcarrier0 + frame_parms->ofdm_symbol_size; + } + int rb = subcarrier0/NR_NB_SC_PER_RB; + + for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { + + sum_re = sum_re + noise_real[ant*nr_srs_info->sc_list_length+sc_idx]; + sum_re2 = sum_re2 + noise_real[ant*nr_srs_info->sc_list_length+sc_idx]*noise_real[ant*nr_srs_info->sc_list_length+sc_idx]; + sum_im = sum_im + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]; + sum_im2 = sum_im2 + noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]*noise_imag[ant*nr_srs_info->sc_list_length+sc_idx]; + + count_estimates++; + if (count_estimates == n_noise_est) { + noise_power_per_rb[rb] = max(sum_re2 / n_noise_est - (sum_re / n_noise_est) * (sum_re / n_noise_est) + + sum_im2 / n_noise_est - (sum_im / n_noise_est) * (sum_im / n_noise_est), 1); + snr_per_rb[rb] = dB_fixed((int32_t)((*signal_power<<factor_bits)/noise_power_per_rb[rb])) - factor_dB; + count_estimates = 0; + sum_re = 0; + sum_re2 = 0; + sum_im = 0; + sum_im2 = 0; + +#ifdef SRS_DEBUG + LOG_I(NR_PHY,"noise_power_per_rb[%i] = %i, snr_per_rb[%i] = %i dB\n", rb, noise_power_per_rb[rb], rb, snr_per_rb[rb]); +#endif + + } + } + } + *noise_power = calc_power(noise_real,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length) + calc_power(noise_imag,frame_parms->nb_antennas_rx*nr_srs_info->sc_list_length); + *snr = dB_fixed((int32_t)((*signal_power<<factor_bits)/(*noise_power))) - factor_dB; + #ifdef SRS_DEBUG - uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12; uint8_t R = srs_pdu->comb_size == 0 ? 2 : 4; for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { @@ -1119,7 +1189,7 @@ int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, } } - LOG_I(NR_PHY,"noise_power = %u\n", *noise_power); + LOG_I(NR_PHY,"noise_power = %u, SNR = %i dB\n", *noise_power, *snr); #endif return 0; diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h index a01106adb5465e96536c67721ddf82e8361c63cf..b0ed3662eac8e52ba7fdbbc9dcf2af80492c1fc6 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_estimation.h @@ -55,6 +55,9 @@ void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id); +int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms, + const int32_t srs_estimated_channel_time[][frame_parms->ofdm_symbol_size]); + void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, NR_DL_FRAME_PARMS *frame_parms, nfapi_nr_pusch_pdu_t *rel15_ul, @@ -63,15 +66,20 @@ void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB, unsigned char symbol, uint32_t nb_re_pusch); -int nr_srs_channel_estimation(PHY_VARS_gNB *gNB, - int frame, - int slot, - nfapi_nr_srs_pdu_t *srs_pdu, - nr_srs_info_t *nr_srs_info, - int32_t *srs_generated_signal, - int32_t **srs_received_signal, - int32_t **srs_estimated_channel_freq, - int32_t **srs_estimated_channel_time, - int32_t **srs_estimated_channel_time_shifted, - uint32_t *noise_power); +int nr_srs_channel_estimation(const PHY_VARS_gNB *gNB, + const int frame, + const int slot, + const nfapi_nr_srs_pdu_t *srs_pdu, + const nr_srs_info_t *nr_srs_info, + const int32_t *srs_generated_signal, + int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)], + int32_t srs_ls_estimated_channel[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)], + int32_t srs_estimated_channel_freq[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)], + int32_t srs_estimated_channel_time[][gNB->frame_parms.ofdm_symbol_size], + int32_t srs_estimated_channel_time_shifted[][gNB->frame_parms.ofdm_symbol_size], + uint32_t *signal_power, + uint32_t *noise_power_per_rb, + uint32_t *noise_power, + int8_t *snr_per_rb, + int8_t *snr); #endif diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index d4d91d7060987bd7438b57dabf92b359a4b86935..110ff321bd992c538e0d88f8bf6a44a59329c151 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -38,7 +38,7 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB); */ void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid); void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid); -void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); +void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid); diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h index eb5c57336829135ee249785ac36756578d08e19b..a6e57fb29826410ecc09241ca0f9794e14d2c522 100644 --- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h +++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h @@ -68,6 +68,6 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue, uint16_t N_n_scid, uint8_t n_scid); -void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); +void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid); #endif diff --git a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c index ab8d915d6e6b452079b193fd923816cf9705a7f1..0a1619f3e062a7d075e1af3d0a64c10c4f67f06f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c +++ b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c @@ -27,7 +27,7 @@ //#define NR_CSIRS_DEBUG -void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) { +void nr_init_csi_rs(const NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) { uint32_t x1, x2; uint8_t reset; int csi_dmrs_init_length = ((fp->N_RB_DL<<4)>>5)+1; @@ -43,12 +43,20 @@ void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) { } } -void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, +void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, int32_t **dataF, - int16_t amp, - nr_csi_rs_info_t *nr_csi_rs_info, - nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params, - int slot){ + const int16_t amp, + nr_csi_info_t *nr_csi_info, + const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params, + const int slot, + uint8_t *N_cdm_groups, + uint8_t *CDM_group_size, + uint8_t *k_prime, + uint8_t *l_prime, + uint8_t *N_ports, + uint8_t *j_cdm, + uint8_t *k_overline, + uint8_t *l_overline) { #ifdef NR_CSIRS_DEBUG LOG_I(NR_PHY, "csi_params->subcarrier_spacing = %i\n", csi_params->subcarrier_spacing); @@ -67,11 +75,11 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, LOG_I(NR_PHY, "csi_params->power_control_offset_ss = %i\n", csi_params->power_control_offset_ss); #endif - int dataF_offset = slot*frame_parms.samples_per_slot_wCP; - uint32_t **nr_gold_csi_rs = nr_csi_rs_info->nr_gold_csi_rs[slot]; + int dataF_offset = slot*frame_parms->samples_per_slot_wCP; + uint32_t **nr_gold_csi_rs = nr_csi_info->nr_gold_csi_rs[slot]; //*8(max allocation per RB)*2(QPSK)) - int csi_rs_length = frame_parms.N_RB_DL<<4; - int16_t mod_csi[frame_parms.symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16))); + int csi_rs_length = frame_parms->N_RB_DL<<4; + int16_t mod_csi[frame_parms->symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16))); uint16_t b = csi_params->freq_domain; uint16_t n, p, k, l, mprime, na, kpn; uint8_t size, ports, kprime, lprime, i, gs; @@ -81,14 +89,14 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, uint8_t fi = 0; double rho, alpha; uint32_t beta = amp; - nr_csi_rs_info->csi_rs_generated_signal_bits = log2_approx(amp); + nr_csi_info->csi_rs_generated_signal_bits = log2_approx(amp); AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n"); // if the scrambling id is not the one previously used to initialize we need to re-initialize the rs - if (csi_params->scramb_id != nr_csi_rs_info->csi_gold_init) { - nr_csi_rs_info->csi_gold_init = csi_params->scramb_id; - nr_init_csi_rs(&frame_parms, nr_csi_rs_info->nr_gold_csi_rs, csi_params->scramb_id); + if (csi_params->scramb_id != nr_csi_info->csi_gold_init) { + nr_csi_info->csi_gold_init = csi_params->scramb_id; + nr_init_csi_rs(frame_parms, nr_csi_info->nr_gold_csi_rs, csi_params->scramb_id); } switch (csi_params->row) { @@ -584,7 +592,7 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, } } - uint16_t start_sc = frame_parms.first_carrier_offset; + uint16_t start_sc = frame_parms->first_carrier_offset; // resource mapping according to 38.211 7.4.1.5.3 for (n=csi_params->start_rb; n<(csi_params->start_rb+csi_params->nr_of_rbs); n++) { @@ -593,7 +601,7 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, for (int s=0 ; s<gs; s++) { // loop over each CDM group size p = s+j[ji]*gs; // port index for (kp=0; kp<=kprime; kp++) { // loop over frequency resource elements within a group - k = (start_sc+(n*NR_NB_SC_PER_RB)+koverline[ji]+kp)%(frame_parms.ofdm_symbol_size); // frequency index of current resource element + k = (start_sc+(n*NR_NB_SC_PER_RB)+koverline[ji]+kp)%(frame_parms->ofdm_symbol_size); // frequency index of current resource element // wf according to tables 7.4.5.3-2 to 7.4.5.3-5 if (kp == 0) wf = 1; @@ -620,17 +628,17 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, // ZP CSI RS if (csi_params->csi_type == 2) { - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = 0; - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = 0; + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = 0; + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = 0; } else { - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15; - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15; + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15; + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15; } #ifdef NR_CSIRS_DEBUG printf("l,k (%d,%d) seq. index %d \t port %d \t (%d,%d)\n",l,k,mprime,p+3000, - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)], - ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)]); + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+(2*dataF_offset)], + ((int16_t*)dataF[p])[((l*frame_parms->ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)]); #endif } } @@ -638,23 +646,25 @@ void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, } } } - nr_csi_rs_info->N_cdm_groups = size; - nr_csi_rs_info->CDM_group_size = gs; - nr_csi_rs_info->kprime = kprime; - nr_csi_rs_info->lprime = lprime; - nr_csi_rs_info->N_ports = ports; - memcpy(nr_csi_rs_info->j,j,16*sizeof(uint8_t)); - memcpy(nr_csi_rs_info->koverline,koverline,16*sizeof(uint8_t)); - memcpy(nr_csi_rs_info->loverline,loverline,16*sizeof(uint8_t)); + if (N_cdm_groups) *N_cdm_groups = size; + if (CDM_group_size) *CDM_group_size = gs; + if (k_prime) *k_prime = kprime; + if (l_prime) *l_prime = lprime; + if (N_ports) *N_ports = ports; + if (j_cdm) memcpy(j_cdm,j,16*sizeof(uint8_t)); + if (k_overline) memcpy(k_overline,koverline,16*sizeof(uint8_t)); + if (l_overline) memcpy(l_overline,loverline,16*sizeof(uint8_t)); #ifdef NR_CSIRS_DEBUG - LOG_I(NR_PHY, "nr_csi_rs_info->N_ports = %d\n", nr_csi_rs_info->N_ports); - LOG_I(NR_PHY, "nr_csi_rs_info->N_cdm_groups = %d\n", nr_csi_rs_info->N_cdm_groups); - LOG_I(NR_PHY, "nr_csi_rs_info->CDM_group_size = %d\n", nr_csi_rs_info->CDM_group_size); - LOG_I(NR_PHY, "nr_csi_rs_info->kprime = %d\n", nr_csi_rs_info->kprime); - LOG_I(NR_PHY, "nr_csi_rs_info->lprime = %d\n", nr_csi_rs_info->lprime); - for(int ji=0; ji<nr_csi_rs_info->N_cdm_groups; ji++) { - LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, nr_csi_rs_info->j[ji], nr_csi_rs_info->koverline[ji], nr_csi_rs_info->loverline[ji]); + if (N_ports) LOG_I(NR_PHY, "nr_csi_info->N_ports = %d\n", *N_ports); + if (N_cdm_groups) LOG_I(NR_PHY, "nr_csi_info->N_cdm_groups = %d\n", *N_cdm_groups); + if (CDM_group_size) LOG_I(NR_PHY, "nr_csi_info->CDM_group_size = %d\n", *CDM_group_size); + if (k_prime) LOG_I(NR_PHY, "nr_csi_info->kprime = %d\n", *k_prime); + if (l_prime) LOG_I(NR_PHY, "nr_csi_info->lprime = %d\n", *l_prime); + if (N_cdm_groups) { + for(int ji=0; ji<*N_cdm_groups; ji++) { + LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, j[ji], koverline[ji], loverline[ji]); + } } #endif } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index d70d991e7b2d7d45f14b4afe9c15fe6ebbb0002f..dc1ed47e0ffd4f7698201a05082a559f4830940e 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -111,9 +111,10 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, // DMRS length is per OFDM symbol uint32_t dmrs_length = n_rb*6; //2(QPSK)*3(per RB)*6(REG per CCE) uint32_t encoded_length = dci_pdu->AggregationLevel*108; //2(QPSK)*9(per RB)*6(REG per CCE) - LOG_D(PHY, "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d),Scrambling_Id %d,ScramblingRNTI %x,PayloadSizeBits %d\n", - rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType, - dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits); + if (dci_pdu->RNTI != 0xFFFF) + LOG_D(PHY, "DL_DCI : rb_offset %d, nb_rb %d, DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d, reg_mapping %d), Scrambling_Id %d, ScramblingRNTI %x, PayloadSizeBits %d\n", + rb_offset, n_rb,dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType, + dci_pdu->ScramblingId,dci_pdu->ScramblingRNTI,dci_pdu->PayloadSizeBits); dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset /// DMRS QPSK modulation @@ -122,11 +123,11 @@ void nr_generate_dci(PHY_VARS_gNB *gNB, nr_modulation(gold_pdcch_dmrs[symb], dmrs_length, DMRS_MOD_ORDER, mod_dmrs[symb]); //Qm = 2 as DMRS is QPSK modulated #ifdef DEBUG_PDCCH_DMRS - if(dci_pdu->RNTI!=0xFFFF) { - for (int i=0; i<dmrs_length>>1; i++) - printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i, - &gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1] ); - } + if(dci_pdu->RNTI!=0xFFFF) { + for (int i=0; i<dmrs_length>>1; i++) + printf("symb %d i %d %p gold seq 0x%08x mod_dmrs %d %d\n", symb, i, + &gold_pdcch_dmrs[symb][i>>5],gold_pdcch_dmrs[symb][i>>5], mod_dmrs[symb][i<<1], mod_dmrs[symb][(i<<1)+1]); + } #endif } @@ -265,7 +266,6 @@ void nr_generate_dci_top(processingData_L1tx_t *msgTx, int16_t amp, NR_DL_FRAME_PARMS *frame_parms) { - for (int i=0; i<msgTx->num_ul_pdcch; i++) nr_generate_dci(msgTx->gNB,&msgTx->ul_pdcch_pdu[i].pdcch_pdu.pdcch_pdu_rel15,txdataF,amp,frame_parms,slot); for (int i=0; i<msgTx->num_dl_pdcch; i++) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index d32fd77b0373cf0e3acea7d61a3aa7283d67a8c8..30dbc39185c125587c105963d263108dce39965a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -123,7 +123,6 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, rel15->dlDmrsSymbPos); n_ptrs = (rel15->rbSize + rel15->PTRSFreqDensity - 1)/rel15->PTRSFreqDensity; } - int16_t mod_ptrs[n_ptrs<<1] __attribute__ ((aligned(16))); /// CRC, coding, interleaving and rate matching AssertFatal(harq->pdu!=NULL,"harq->pdu is null\n"); @@ -302,12 +301,14 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx, /* calculate if current symbol is PTRS symbols */ ptrs_idx = 0; - + int16_t *mod_ptrs = NULL; if(rel15->pduBitmap & 0x1) { ptrs_symbol = is_ptrs_symbol(l,dlPtrsSymPos); if(ptrs_symbol) { /* PTRS QPSK Modulation for each OFDM symbol in a slot */ LOG_D(PHY,"Doing ptrs modulation for symbol %d, n_ptrs %d\n",l,n_ptrs); + int16_t mod_ptrsBuf[n_ptrs<<1] __attribute__ ((aligned(16))); + mod_ptrs =mod_ptrsBuf; nr_modulation(pdsch_dmrs[l][rel15->SCID], (n_ptrs<<1), DMRS_MOD_ORDER, mod_ptrs); } } diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index f0f9f4fe34f3742257f1b8856adab2ca6fddae58..8672f3ae29aadf3d4d0bcf8e2d37864a3c448319 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -123,7 +123,6 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, bzero(dlsch,sizeof(NR_gNB_DLSCH_t)); dlsch->Kmimo = Kmimo; dlsch->Mdlharq = Mdlharq; - dlsch->Mlimit = 4; dlsch->Nsoft = Nsoft; int txdataf_size = frame_parms->N_RB_DL*NR_SYMBOLS_PER_SLOT*NR_NB_SC_PER_RB*8; // max pdsch encoded length for each layer diff --git a/openair1/PHY/NR_TRANSPORT/nr_pbch.c b/openair1/PHY/NR_TRANSPORT/nr_pbch.c index fc7df4649606902a073dd149197e6fbf49cb3ae7..278c2dfd58c8061d7b2c8d4c621e1373ae0dac7d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_pbch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_pbch.c @@ -35,6 +35,7 @@ #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/LTE_REFSIG/lte_refsig.h" #include "PHY/sse_intrin.h" +#include "executables/softmodem-common.h" //#define DEBUG_PBCH //#define DEBUG_PBCH_ENCODING @@ -248,6 +249,9 @@ int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu, for (int i=0; i<NR_PBCH_PDU_BITS; i++) pbch->pbch_a |= ((pbch_pdu[i>>3]>>(7-(i&7)))&1)<<i; + // NSA to signal no coreset0 + const int ssb_sc_offset = get_softmodem_params()->sa ? config->ssb_table.ssb_subcarrier_offset.value : 31; + #ifdef DEBUG_PBCH_ENCODING for (int i=0; i<3; i++) printf("pbch_pdu[%d]: 0x%02x\n", i, pbch_pdu[i]); @@ -265,7 +269,7 @@ int nr_generate_pbch(nfapi_nr_dl_tti_ssb_pdu *ssb_pdu, for (int i=0; i<3; i++) pbch->pbch_a |= ((ssb_index>>(5-i))&1)<<(29+i); // resp. 6th, 5th and 4th bits of ssb_index else - pbch->pbch_a |= ((config->ssb_table.ssb_subcarrier_offset.value>>4)&1)<<29; //MSB of k_SSB (bit index 4) + pbch->pbch_a |= ((ssb_sc_offset>>4)&1)<<29; //MSB of k_SSB (bit index 4) LOG_D(PHY,"After extra byte: pbch_a = 0x%08x\n",pbch->pbch_a); diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index e3b7efacfb8d53b30221eb452754d7676488386f..5437a9bb812d6a9519b08f42efa9bde001ddaea9 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -121,11 +121,11 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB, const NR_DL_FRAME_ @param slot Slot number @param harq_pid HARQ process ID */ -int nr_rx_pusch(PHY_VARS_gNB *gNB, - uint8_t UE_id, - uint32_t frame, - uint8_t slot, - unsigned char harq_pid); +void nr_rx_pusch(PHY_VARS_gNB *gNB, + uint8_t UE_id, + uint32_t frame, + uint8_t slot, + unsigned char harq_pid); /** \brief This function performs RB extraction (signal and channel estimates) (currently signal only until channel estimation and compensation are implemented) @param rxdataF pointer to the received frequency domain signal @@ -330,19 +330,27 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, int slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, - int32_t **srs_received_signal); + int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)]); void init_prach_list(PHY_VARS_gNB *gNB); void init_prach_ru_list(RU_t *ru); void free_nr_ru_prach_entry(RU_t *ru, int prach_id); uint8_t get_nr_prach_duration(uint8_t prach_format); -void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms, +void nr_generate_csi_rs(const NR_DL_FRAME_PARMS *frame_parms, int32_t **dataF, - int16_t amp, - nr_csi_rs_info_t *nr_csi_rs_info, - nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params, - int slot); + const int16_t amp, + nr_csi_info_t *nr_csi_info, + const nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params, + const int slot, + uint8_t *N_cdm_groups, + uint8_t *CDM_group_size, + uint8_t *k_prime, + uint8_t *l_prime, + uint8_t *N_ports, + uint8_t *j_cdm, + uint8_t *k_overline, + uint8_t *l_overline); void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id); @@ -362,6 +370,7 @@ void nr_decode_pucch1(int32_t **rxdataF, uint8_t nr_bit); void nr_decode_pucch2(PHY_VARS_gNB *gNB, + int frame, int slot, nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu, nfapi_nr_pucch_pdu_t* pucch_pdu); @@ -372,10 +381,5 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu, nfapi_nr_pucch_pdu_t* pucch_pdu); -void nr_decode_pucch2(PHY_VARS_gNB *gNB, - int slot, - nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu, - nfapi_nr_pucch_pdu_t* pucch_pdu); - #endif /*__NR_TRANSPORT__H__*/ diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c index 5c6839366c8ce85b99308ef5d5c2f7bf5b5eb728..e56a4607e2d9a130e204c347db3a714f130ad4c3 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch.c @@ -68,12 +68,20 @@ void nr_fill_ulsch(PHY_VARS_gNB *gNB, ulsch->rnti = ulsch_pdu->rnti; //ulsch->rnti_type; ulsch->harq_mask |= 1<<harq_pid; - ulsch->harq_process_id[slot] = harq_pid; - ulsch->harq_processes[harq_pid]->frame=frame; - ulsch->harq_processes[harq_pid]->slot=slot; - ulsch->harq_processes[harq_pid]->handled= 0; - ulsch->harq_processes[harq_pid]->status= NR_ACTIVE; + NR_UL_gNB_HARQ_t *harq = ulsch->harq_processes[harq_pid]; + harq->frame=frame; + harq->slot=slot; + harq->handled = 0; + harq->status= NR_ACTIVE; + harq->new_rx = harq->ndi != ulsch_pdu->pusch_data.new_data_indicator; + if (harq->new_rx) { + harq->ndi = ulsch_pdu->pusch_data.new_data_indicator; + harq->round = 0; + } else { + harq->round++; + } + memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t)); LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid); diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index 355dbafc6f79df48fbc2134e8e804a516dbf72e6..424630a192c878fd46fff822ceae0e86b7fc2f47 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -102,7 +102,6 @@ NR_gNB_ULSCH_t *new_gNB_ulsch(uint8_t max_ldpc_iterations, uint16_t N_RB_UL) ulsch = (NR_gNB_ULSCH_t *)malloc16_clear(sizeof(NR_gNB_ULSCH_t)); ulsch->max_ldpc_iterations = max_ldpc_iterations; - ulsch->Mlimit = 4; for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) { @@ -137,10 +136,8 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) ulsch->rnti_type = 0; ulsch->cyclicShift = 0; ulsch->cooperation_flag = 0; - ulsch->Mlimit = 0; ulsch->max_ldpc_iterations = 0; ulsch->last_iteration_cnt = 0; - for (i=0;i<NR_MAX_SLOTS_PER_FRAME;i++) ulsch->harq_process_id[i] = 0; for (i=0; i<NR_MAX_ULSCH_HARQ_PROCESSES; i++) { if (ulsch->harq_processes[i]){ @@ -433,7 +430,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, uint8_t n_layers = pusch_pdu->nrOfLayers; // ------------------------------------------------------------------ - if (!ulsch_llr) { + if (!ulsch_llr) { LOG_E(PHY,"ulsch_decoding.c: NULL ulsch_llr pointer\n"); return 1; } diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index 4b8315e1ce488b4f43dde0acfca721deb5bed1c0..ac4c6f35e07c2447ee77674fe26f5158ef3bb80d 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -1891,11 +1891,11 @@ uint8_t nr_ulsch_zero_forcing_rx_2layers(int **rxdataF_comp, //============================================================================================== /* Main Function */ -int nr_rx_pusch(PHY_VARS_gNB *gNB, - uint8_t ulsch_id, - uint32_t frame, - uint8_t slot, - unsigned char harq_pid) +void nr_rx_pusch(PHY_VARS_gNB *gNB, + uint8_t ulsch_id, + uint32_t frame, + uint8_t slot, + unsigned char harq_pid) { uint8_t aarx, aatx; @@ -2149,6 +2149,4 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB, rxdataF_ext_offset += gNB->pusch_vars[ulsch_id]->ul_valid_re_per_slot[symbol]; } } // symbol loop - - return 0; } diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 5617b8e58bb48784273981ee7dcd9ae892ec68c3..2f8a288c662ca16b781b645d249b98b728be1cf1 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -278,16 +278,30 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, uint8_t maxpos=0; uint8_t index=0; + int nb_re_pucch = 12*pucch_pdu->prb_size; // prb size is 1 + int32_t rp[frame_parms->nb_antennas_rx][pucch_pdu->nr_of_symbols][nb_re_pucch],*tmp_rp; + for (int l=0; l<pucch_pdu->nr_of_symbols; l++) { l2 = l+pucch_pdu->start_symbol_index; + re_offset[l] = (12*prb_offset[l]) + frame_parms->first_carrier_offset; if (re_offset[l]>= frame_parms->ofdm_symbol_size) re_offset[l]-=frame_parms->ofdm_symbol_size; - - AssertFatal(re_offset[l]+12 < frame_parms->ofdm_symbol_size,"pucch straddles DC carrier, handle this!\n"); + for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) { - c16_t *r=(c16_t*)&rxdataF[aa][soffset+(l2*frame_parms->ofdm_symbol_size)+re_offset[l]]; - for (n=0;n<12;n++) { + tmp_rp = &rxdataF[aa][soffset + l2*frame_parms->ofdm_symbol_size]; + if(re_offset[l] + nb_re_pucch > frame_parms->ofdm_symbol_size) { + int neg_length = frame_parms->ofdm_symbol_size-re_offset[l]; + int pos_length = nb_re_pucch-neg_length; + memcpy1((void*)rp[aa][l],(void*)&tmp_rp[re_offset[l]],neg_length*sizeof(int32_t)); + memcpy1((void*)&rp[aa][l][neg_length],(void*)tmp_rp,pos_length*sizeof(int32_t)); + } + else + memcpy1((void*)rp[aa][l],(void*)&tmp_rp[re_offset[l]],nb_re_pucch*sizeof(int32_t)); + + c16_t *r = (c16_t*)&rp[aa][l]; + + for (n=0;n<nb_re_pucch;n++) { xr[aa][l][n].r = (int32_t)x_re[l][n] * r[n].r + (int32_t)x_im[l][n] * r[n].i; xr[aa][l][n].i = (int32_t)x_re[l][n] * r[n].i - (int32_t)x_im[l][n] * r[n].r; #ifdef DEBUG_NR_PUCCH_RX @@ -317,8 +331,8 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, corr[aa][l].r += xr[aa][l][n].r * idft12_re[seq_index][n] + xr[aa][l][n].i * idft12_im[seq_index][n]; corr[aa][l].i += xr[aa][l][n].r * idft12_im[seq_index][n] - xr[aa][l][n].i * idft12_re[seq_index][n]; } - corr[aa][l].r >>= 31; - corr[aa][l].i >>= 31; + corr[aa][l].r >>= 31; + corr[aa][l].i >>= 31; } } LOG_D(PHY,"PUCCH IDFT[%d/%d] = (%ld,%ld)=>%f\n", @@ -385,9 +399,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, gNB->measurements.n0_subband_power_tot_dB[prb_offset[1]]); int SNRtimes10,sigenergy=0; for (int aa=0;aa<frame_parms->nb_antennas_rx;aa++) - sigenergy += signal_energy_nodc(&rxdataF[aa][soffset+ - (pucch_pdu->start_symbol_index*frame_parms->ofdm_symbol_size)+ - re_offset[0]],12); + sigenergy += signal_energy_nodc(rp[aa][0],12); SNRtimes10 = xrtmag_dBtimes10-(10*max_n0); int cqi; if (SNRtimes10 < -640) cqi=0; @@ -1124,6 +1136,7 @@ void init_pucch2_luts() { void nr_decode_pucch2(PHY_VARS_gNB *gNB, + int frame, int slot, nfapi_nr_uci_pucch_pdu_format_2_3_4_t* uci_pdu, nfapi_nr_pucch_pdu_t* pucch_pdu) { @@ -1708,13 +1721,19 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB, uci_pdu->pduBitmap|=2; uci_pdu->harq.harq_payload = (uint8_t*)malloc(harq_bytes); uci_pdu->harq.harq_crc = decoderState; + LOG_D(PHY,"[DLSCH/PDSCH/PUCCH2] %d.%d HARQ bytes (%d) Decoder state %d\n", + frame,slot,harq_bytes,decoderState); int i=0; for (;i<harq_bytes-1;i++) { uci_pdu->harq.harq_payload[i] = decodedPayload[0] & 255; + LOG_D(PHY,"[DLSCH/PDSCH/PUCCH2] %d.%d HARQ paylod (%d) = %d\n", + frame,slot,i,uci_pdu->harq.harq_payload[i]); decodedPayload[0]>>=8; } bit_left = pucch_pdu->bit_len_harq-((harq_bytes-1)<<3); uci_pdu->harq.harq_payload[i] = decodedPayload[0] & ((1<<bit_left)-1); + LOG_D(PHY,"[DLSCH/PDSCH/PUCCH2] %d.%d HARQ paylod (%d) = %d\n", + frame,slot,i,uci_pdu->harq.harq_payload[i]); decodedPayload[0] >>= pucch_pdu->bit_len_harq; } diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index 2d7aefdee082b5b6baeb03e104de8a828aaf791f..39c3846db596df01533a3fc8831136daec828356 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -98,7 +98,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, int slot, nfapi_nr_srs_pdu_t *srs_pdu, nr_srs_info_t *nr_srs_info, - int32_t **srs_received_signal) { + int32_t srs_received_signal[][gNB->frame_parms.ofdm_symbol_size*(1<<srs_pdu->num_symbols)]) { if(nr_srs_info->sc_list_length == 0) { LOG_E(NR_PHY, "(%d.%d) nr_srs_info was not generated yet!\n", frame, slot); @@ -113,6 +113,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, uint64_t symbol_offset = (n_symbols+l0)*frame_parms->ofdm_symbol_size; int32_t *rx_signal; + bool no_srs_signal = true; for (int ant = 0; ant < frame_parms->nb_antennas_rx; ant++) { memset(srs_received_signal[ant], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t)); @@ -121,6 +122,10 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, for(int sc_idx = 0; sc_idx < nr_srs_info->sc_list_length; sc_idx++) { srs_received_signal[ant][nr_srs_info->sc_list[sc_idx]] = rx_signal[nr_srs_info->sc_list[sc_idx]]; + if (rx_signal[nr_srs_info->sc_list[sc_idx]] != 0) { + no_srs_signal = false; + } + #ifdef SRS_DEBUG uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_pdu->bwp_start*12; int subcarrier_log = nr_srs_info->sc_list[sc_idx]-subcarrier_offset; @@ -140,5 +145,11 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, #endif } } - return 0; + + if (no_srs_signal) { + LOG_W(NR_PHY, "No SRS signal\n"); + return -1; + } else { + return 0; + } } \ No newline at end of file diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c index 8936a69e70b764738ecb9cc818b1890116346282..ba7e61afe67b6972d542d35144c9ced773845b9c 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_dl_channel_estimation.c @@ -1657,7 +1657,6 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, RX_type_t rx_type) { //#define DEBUG_DL_PTRS 1 - int16_t *phase_per_symbol = NULL; int32_t *ptrs_re_symbol = NULL; int8_t ret = 0; /* harq specific variables */ @@ -1701,20 +1700,20 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, } /* loop over antennas */ for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) { - phase_per_symbol = (int16_t*)pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx]; + c16_t *phase_per_symbol = (c16_t*)pdsch_vars[gNB_id]->ptrs_phase_per_slot[aarx]; ptrs_re_symbol = (int32_t*)pdsch_vars[gNB_id]->ptrs_re_per_slot[aarx]; ptrs_re_symbol[symbol] = 0; - phase_per_symbol[(2*symbol)+1] = 0; // Imag + phase_per_symbol[symbol].i = 0; // Imag /* set DMRS estimates to 0 angle with magnitude 1 */ if(is_dmrs_symbol(symbol,*dmrsSymbPos)) { /* set DMRS real estimation to 32767 */ - phase_per_symbol[2*symbol]=(int16_t)((1<<15)-1); // 32767 + phase_per_symbol[symbol].r=INT16_MAX; // 32767 #ifdef DEBUG_DL_PTRS - printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[2*symbol],phase_per_symbol[(2*symbol)+1]); + printf("[PHY][PTRS]: DMRS Symbol %d -> %4d + j*%4d\n", symbol, phase_per_symbol[symbol].r,phase_per_symbol[symbol].i); #endif } else { // real ptrs value is set to 0 - phase_per_symbol[2*symbol] = 0; // Real + phase_per_symbol[symbol].r = 0; // Real } if(dlsch0_harq->status == ACTIVE) { @@ -1740,7 +1739,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, symbol,frame_parms->ofdm_symbol_size, (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(symbol * nb_re_pdsch)], ue->nr_gold_pdsch[gNB_id][nr_slot_rx][symbol][0], - &phase_per_symbol[2* symbol], + (int16_t*)&phase_per_symbol[symbol], &ptrs_re_symbol[symbol]); } }// HARQ 0 @@ -1752,7 +1751,7 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, /*------------------------------------------------------------------------------------------------------- */ /* If L-PTRS is > 0 then we need interpolation */ if(*L_ptrs > 0) { - ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, phase_per_symbol, *startSymbIndex, *nbSymb); + ret = nr_ptrs_process_slot(*dmrsSymbPos, *ptrsSymbPos, (int16_t*)phase_per_symbol, *startSymbIndex, *nbSymb); if(ret != 0) { LOG_W(PHY,"[PTRS] Compensation is skipped due to error in PTRS slot processing !!\n"); } @@ -1771,11 +1770,11 @@ void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, /* Skip rotation if the slot processing is wrong */ if((!is_dmrs_symbol(i,*dmrsSymbPos)) && (ret == 0)) { #ifdef DEBUG_DL_PTRS - printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[2* i],phase_per_symbol[(2* i) +1]); + printf("[PHY][DL][PTRS]: Rotate Symbol %2d with %d + j* %d\n", i, phase_per_symbol[i].r,phase_per_symbol[i].i); #endif - rotate_cpx_vector((int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], - &phase_per_symbol[2* i], - (int16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + rotate_cpx_vector((c16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], + &phase_per_symbol[i], + (c16_t*)&pdsch_vars[gNB_id]->rxdataF_comp0[aarx][(i * (*nb_rb) * NR_NB_SC_PER_RB)], ((*nb_rb) * NR_NB_SC_PER_RB), 15); }// if not DMRS Symbol }// symbol loop diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c index 79fd7a3dd2352bce0d8a27fa5ee85e62a3cd7435..43944b2fa876538cf4a04a28bf86ff1c7812098d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c +++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c @@ -33,16 +33,103 @@ #include <stdlib.h> #include <string.h> +#include "executables/nr-softmodem-common.h" #include "nr_transport_proto_ue.h" #include "PHY/phy_extern_nr_ue.h" #include "common/utils/nr/nr_common.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" #include "PHY/NR_UE_ESTIMATION/filt16a_32.h" +// 10*log10(pow(2,30)) +#define pow_2_30_dB 90 //#define NR_CSIRS_DEBUG +//#define NR_CSIIM_DEBUG -bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, int symbol) { +void nr_det_A_MF_2x2(int32_t *a_mf_00, + int32_t *a_mf_01, + int32_t *a_mf_10, + int32_t *a_mf_11, + int32_t *det_fin, + const unsigned short nb_rb) { + + int16_t nr_conjug2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1} ; + + __m128i ad_re_128, bc_re_128, det_re_128; + + __m128i *a_mf_00_128 = (__m128i *)a_mf_00; + __m128i *a_mf_01_128 = (__m128i *)a_mf_01; + __m128i *a_mf_10_128 = (__m128i *)a_mf_10; + __m128i *a_mf_11_128 = (__m128i *)a_mf_11; + __m128i *det_fin_128 = (__m128i *)det_fin; + + for (int rb = 0; rb<3*nb_rb; rb++) { + + //complex multiplication (I_a+jQ_a)(I_d+jQ_d) = (I_aI_d - Q_aQ_d) + j(Q_aI_d + I_aQ_d) + //The imag part is often zero, we compute only the real part + ad_re_128 = _mm_sign_epi16(a_mf_00_128[0],*(__m128i*)&nr_conjug2[0]); + ad_re_128 = _mm_madd_epi16(ad_re_128,a_mf_11_128[0]); //Re: I_a0*I_d0 - Q_a1*Q_d1 + + //complex multiplication (I_b+jQ_b)(I_c+jQ_c) = (I_bI_c - Q_bQ_c) + j(Q_bI_c + I_bQ_c) + //The imag part is often zero, we compute only the real part + bc_re_128 = _mm_sign_epi16(a_mf_01_128[0],*(__m128i*)&nr_conjug2[0]); + bc_re_128 = _mm_madd_epi16(bc_re_128,a_mf_10_128[0]); //Re: I_b0*I_c0 - Q_b1*Q_c1 + + det_re_128 = _mm_sub_epi32(ad_re_128, bc_re_128); + + //det in Q30 format + det_fin_128[0] = _mm_abs_epi32(det_re_128); + + det_fin_128+=1; + a_mf_00_128+=1; + a_mf_01_128+=1; + a_mf_10_128+=1; + a_mf_11_128+=1; + } + _mm_empty(); + _m_empty(); +} + +void nr_squared_matrix_element(int32_t *a, + int32_t *a_sq, + const unsigned short nb_rb) { + __m128i *a_128 = (__m128i *)a; + __m128i *a_sq_128 = (__m128i *)a_sq; + for (int rb=0; rb<3*nb_rb; rb++) { + a_sq_128[0] = _mm_madd_epi16(a_128[0], a_128[0]); + a_sq_128+=1; + a_128+=1; + } + _mm_empty(); + _m_empty(); +} + +void nr_numer_2x2(int32_t *a_00_sq, + int32_t *a_01_sq, + int32_t *a_10_sq, + int32_t *a_11_sq, + int32_t *num_fin, + const unsigned short nb_rb) { + __m128i *a_00_sq_128 = (__m128i *)a_00_sq; + __m128i *a_01_sq_128 = (__m128i *)a_01_sq; + __m128i *a_10_sq_128 = (__m128i *)a_10_sq; + __m128i *a_11_sq_128 = (__m128i *)a_11_sq; + __m128i *num_fin_128 = (__m128i *)num_fin; + for (int rb=0; rb<3*nb_rb; rb++) { + __m128i sq_a_plus_sq_d_128 = _mm_add_epi32(a_00_sq_128[0], a_11_sq_128[0]); + __m128i sq_b_plus_sq_c_128 = _mm_add_epi32(a_01_sq_128[0], a_10_sq_128[0]); + num_fin_128[0] = _mm_add_epi32(sq_a_plus_sq_d_128, sq_b_plus_sq_c_128); + num_fin_128+=1; + a_00_sq_128+=1; + a_01_sq_128+=1; + a_10_sq_128+=1; + a_11_sq_128+=1; + } + _mm_empty(); + _m_empty(); +} + +bool is_csi_rs_in_symbol(const fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, const int symbol) { bool ret = false; @@ -90,17 +177,27 @@ bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, i return ret; } -int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, - nr_csi_rs_info_t *nr_csi_rs_info, - int32_t **csi_rs_received_signal) { +int nr_get_csi_rs_signal(const PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + const nr_csi_info_t *nr_csi_info, + const uint8_t N_cdm_groups, + const uint8_t CDM_group_size, + const uint8_t k_prime, + const uint8_t l_prime, + const uint8_t *j_cdm, + const uint8_t *k_overline, + const uint8_t *l_overline, + int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP], + uint32_t *rsrp, + int *rsrp_dBm) { int32_t **rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; - NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + uint16_t meas_count = 0; + uint32_t rsrp_sum = 0; for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { - memset(csi_rs_received_signal[ant_rx], 0, frame_parms->samples_per_frame_wCP*sizeof(int32_t)); for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { @@ -109,36 +206,41 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue, continue; } - for (int cdm_id = 0; cdm_id < nr_csi_rs_info->N_cdm_groups; cdm_id++) { - for (int s = 0; s < nr_csi_rs_info->CDM_group_size; s++) { + for (int cdm_id = 0; cdm_id < N_cdm_groups; cdm_id++) { + for (int s = 0; s < CDM_group_size; s++) { // loop over frequency resource elements within a group - for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) { + for (int kp = 0; kp <= k_prime; kp++) { - uint16_t k = (frame_parms->first_carrier_offset + (rb*NR_NB_SC_PER_RB)+nr_csi_rs_info->koverline[cdm_id] + kp) % frame_parms->ofdm_symbol_size; + uint16_t k = (frame_parms->first_carrier_offset + (rb*NR_NB_SC_PER_RB)+k_overline[cdm_id] + kp) % frame_parms->ofdm_symbol_size; // loop over time resource elements within a group - for (int lp = 0; lp <= nr_csi_rs_info->lprime; lp++) { - uint16_t symb = lp + nr_csi_rs_info->loverline[cdm_id]; + for (int lp = 0; lp <= l_prime; lp++) { + uint16_t symb = lp + l_overline[cdm_id]; uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size; - int16_t *rx_signal = (int16_t*)&rxdataF[ant_rx][symbol_offset]; - int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; - rx_csi_rs_signal[k<<1] = rx_signal[k<<1]; - rx_csi_rs_signal[(k<<1)+1] = rx_signal[(k<<1)+1]; + c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset]; + c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; + rx_csi_rs_signal[k].r = rx_signal[k].r; + rx_csi_rs_signal[k].i = rx_signal[k].i; + + rsrp_sum += (((int32_t)(rx_csi_rs_signal[k].r)*rx_csi_rs_signal[k].r) + + ((int32_t)(rx_csi_rs_signal[k].i)*rx_csi_rs_signal[k].i)); + + meas_count++; #ifdef NR_CSIRS_DEBUG int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP; - uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size; - int16_t *tx_csi_rs_signal = (int16_t*)&nr_csi_rs_info->csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; + uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size; + c16_t *tx_csi_rs_signal = (c16_t*)&nr_csi_info->csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; LOG_I(NR_PHY, "l,k (%2d,%4d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n", symb, k, port_tx+3000, - tx_csi_rs_signal[k<<1], - tx_csi_rs_signal[(k<<1)+1], + tx_csi_rs_signal[k].r, + tx_csi_rs_signal[k].i, ant_rx, - rx_csi_rs_signal[k<<1], - rx_csi_rs_signal[(k<<1)+1]); + rx_csi_rs_signal[k].r, + rx_csi_rs_signal[k].i); #endif } } @@ -147,10 +249,19 @@ int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue, } } + + *rsrp = rsrp_sum/meas_count; + *rsrp_dBm = dB_fixed(*rsrp) + 30 - pow_2_30_dB + - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size); + +#ifdef NR_CSIRS_DEBUG + LOG_I(NR_PHY, "RSRP = %i (%i dBm)\n", *rsrp, *rsrp_dBm); +#endif + return 0; } -uint32_t calc_power_csirs(uint16_t *x, fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu) { +uint32_t calc_power_csirs(const uint16_t *x, const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu) { uint64_t sum_x = 0; uint64_t sum_x2 = 0; uint16_t size = 0; @@ -165,25 +276,38 @@ uint32_t calc_power_csirs(uint16_t *x, fapi_nr_dl_config_csirs_pdu_rel15_t *csir return sum_x2/size - (sum_x/size)*(sum_x/size); } -int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, - UE_nr_rxtx_proc_t *proc, - fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, - nr_csi_rs_info_t *nr_csi_rs_info, - int32_t **csi_rs_generated_signal, - int32_t **csi_rs_received_signal, - int32_t ***csi_rs_estimated_channel_freq, +int nr_csi_rs_channel_estimation(const PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + const nr_csi_info_t *nr_csi_info, + const int32_t **csi_rs_generated_signal, + const int32_t csi_rs_received_signal[][ue->frame_parms.samples_per_slot_wCP], + const uint8_t N_cdm_groups, + const uint8_t CDM_group_size, + const uint8_t k_prime, + const uint8_t l_prime, + const uint8_t N_ports, + const uint8_t *j_cdm, + const uint8_t *k_overline, + const uint8_t *l_overline, + int32_t csi_rs_ls_estimated_channel[][N_ports][ue->frame_parms.ofdm_symbol_size], + int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size], + int16_t *log2_re, + int16_t *log2_maxh, uint32_t *noise_power) { - NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; - int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP; + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + const int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP; *noise_power = 0; + int maxh = 0; + int count = 0; for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { /// LS channel estimation - for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) { - memset(nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t)); + for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) { + memset(csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t)); } for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { @@ -193,32 +317,32 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, continue; } - for (int cdm_id = 0; cdm_id < nr_csi_rs_info->N_cdm_groups; cdm_id++) { - for (int s = 0; s < nr_csi_rs_info->CDM_group_size; s++) { + for (int cdm_id = 0; cdm_id < N_cdm_groups; cdm_id++) { + for (int s = 0; s < CDM_group_size; s++) { - uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size; + uint16_t port_tx = s+j_cdm[cdm_id]*CDM_group_size; // loop over frequency resource elements within a group - for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) { + for (int kp = 0; kp <= k_prime; kp++) { uint16_t kinit = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; - uint16_t k = kinit + nr_csi_rs_info->koverline[cdm_id] + kp; + uint16_t k = kinit + k_overline[cdm_id] + kp; // loop over time resource elements within a group - for (int lp = 0; lp <= nr_csi_rs_info->lprime; lp++) { - uint16_t symb = lp + nr_csi_rs_info->loverline[cdm_id]; + for (int lp = 0; lp <= l_prime; lp++) { + uint16_t symb = lp + l_overline[cdm_id]; uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size; - int16_t *tx_csi_rs_signal = (int16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; - int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; - int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; + c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; + c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; + c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; - int16_t csi_rs_ls_estimated_channel_re = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[k<<1] + (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[(k<<1)+1])>>nr_csi_rs_info->csi_rs_generated_signal_bits); - int16_t csi_rs_ls_estimated_channel_im = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[(k<<1)+1] - (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[k<<1])>>nr_csi_rs_info->csi_rs_generated_signal_bits); + int16_t csi_rs_ls_estimated_channel_re = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].r + (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].i)>>nr_csi_info->csi_rs_generated_signal_bits); + int16_t csi_rs_ls_estimated_channel_im = (int16_t)(((int32_t)tx_csi_rs_signal[k].r*rx_csi_rs_signal[k].i - (int32_t)tx_csi_rs_signal[k].i*rx_csi_rs_signal[k].r)>>nr_csi_info->csi_rs_generated_signal_bits); // This is not just the LS estimation for each (k,l), but also the sum of the different contributions // for the sake of optimizing the memory used. - csi_rs_ls_estimated_channel[kinit<<1] += csi_rs_ls_estimated_channel_re; - csi_rs_ls_estimated_channel[(kinit<<1)+1] += csi_rs_ls_estimated_channel_im; + csi_rs_ls_estimated_channel16[kinit].r += csi_rs_ls_estimated_channel_re; + csi_rs_ls_estimated_channel16[kinit].i += csi_rs_ls_estimated_channel_im; } } } @@ -232,16 +356,16 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, } for(int k = 0; k<frame_parms->ofdm_symbol_size; k++) { LOG_I(NR_PHY, "l,k (%2d,%4d) | ", symb, k); - for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) { + for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) { uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size; - int16_t *tx_csi_rs_signal = (int16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; - int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; - int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; + c16_t *tx_csi_rs_signal = (c16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset]; + c16_t *rx_csi_rs_signal = (c16_t*)&csi_rs_received_signal[ant_rx][symbol_offset]; + c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; printf("port_tx %d --> ant_rx %d, tx (%4d,%4d), rx (%4d,%4d), ls (%4d,%4d) | ", port_tx+3000, ant_rx, - tx_csi_rs_signal[k<<1], tx_csi_rs_signal[(k<<1)+1], - rx_csi_rs_signal[k<<1], rx_csi_rs_signal[(k<<1)+1], - csi_rs_ls_estimated_channel[k<<1], csi_rs_ls_estimated_channel[(k<<1)+1]); + tx_csi_rs_signal[k].r, tx_csi_rs_signal[k].i, + rx_csi_rs_signal[k].r, rx_csi_rs_signal[k].i, + csi_rs_ls_estimated_channel16[k].r, csi_rs_ls_estimated_channel16[k].i); } printf("\n"); } @@ -250,7 +374,7 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, /// Channel interpolation - for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) { + for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) { memset(csi_rs_estimated_channel_freq[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t)); } @@ -261,37 +385,40 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, continue; } + count++; + uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; - for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) { - int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][k]; + for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) { + int16_t *csi_rs_ls_estimated_channel16 = (int16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][k]; int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k]; if( (k == 0) || (k == frame_parms->first_carrier_offset) ) { // Start of OFDM symbol case or first occupied subcarrier case - multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16, 24); + multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16, 24); } else if( ( (k + NR_NB_SC_PER_RB) >= frame_parms->ofdm_symbol_size) || (rb == (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs-1)) ) { // End of OFDM symbol case or Last occupied subcarrier case - multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24); + multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24); } else { // Middle case - multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24); + multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel16, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24); } } } /// Power noise estimation - uint16_t noise_real[frame_parms->nb_antennas_rx][nr_csi_rs_info->N_ports][csirs_config_pdu->nr_of_rbs]; - uint16_t noise_imag[frame_parms->nb_antennas_rx][nr_csi_rs_info->N_ports][csirs_config_pdu->nr_of_rbs]; + uint16_t noise_real[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs]; + uint16_t noise_imag[frame_parms->nb_antennas_rx][N_ports][csirs_config_pdu->nr_of_rbs]; for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) { continue; } uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; - for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) { - int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][k]; - int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k]; - noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel[0]-csi_rs_estimated_channel16[0]); - noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel[1]-csi_rs_estimated_channel16[1]); + for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) { + c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][k]; + c16_t *csi_rs_estimated_channel16 = (c16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k]; + noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel16->r-csi_rs_estimated_channel16->r); + noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel16->i-csi_rs_estimated_channel16->i); + maxh = cmax3(maxh, abs(csi_rs_estimated_channel16->r), abs(csi_rs_estimated_channel16->i)); } } - for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) { + for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) { *noise_power += (calc_power_csirs(noise_real[ant_rx][port_tx], csirs_config_pdu) + calc_power_csirs(noise_imag[ant_rx][port_tx],csirs_config_pdu)); } @@ -301,13 +428,13 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, (k - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB : (k + frame_parms->ofdm_symbol_size - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB; LOG_I(NR_PHY, "(k = %4d) |\t", k); - for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) { - int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; - int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][0]; + for(uint16_t port_tx = 0; port_tx<N_ports; port_tx++) { + c16_t *csi_rs_ls_estimated_channel16 = (c16_t*)&csi_rs_ls_estimated_channel[ant_rx][port_tx][0]; + c16_t *csi_rs_estimated_channel16 = (c16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][0]; printf("Channel port_tx %d --> ant_rx %d : ls (%4d,%4d), int (%4d,%4d), noise (%4d,%4d) | ", port_tx+3000, ant_rx, - csi_rs_ls_estimated_channel[k<<1], csi_rs_ls_estimated_channel[(k<<1)+1], - csi_rs_estimated_channel16[k<<1], csi_rs_estimated_channel16[(k<<1)+1], + csi_rs_ls_estimated_channel16[k].r, csi_rs_ls_estimated_channel16[k].i, + csi_rs_estimated_channel16[k].r, csi_rs_estimated_channel16[k].i, rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb], rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb]); } @@ -317,7 +444,9 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, } - *noise_power /= (frame_parms->nb_antennas_rx*nr_csi_rs_info->N_ports); + *noise_power /= (frame_parms->nb_antennas_rx*N_ports); + *log2_maxh = log2_approx(maxh-1); + *log2_re = log2_approx(count-1); #ifdef NR_CSIRS_DEBUG LOG_I(NR_PHY, "Noise power estimation based on CSI-RS: %i\n", *noise_power); @@ -326,7 +455,371 @@ int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue, return 0; } +int nr_csi_rs_ri_estimation(const PHY_VARS_NR_UE *ue, + const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + const nr_csi_info_t *nr_csi_info, + const uint8_t N_ports, + int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size], + const int16_t log2_maxh, + uint8_t *rank_indicator) { + + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + const int16_t cond_dB_threshold = 5; + int count = 0; + *rank_indicator = 0; + + if (ue->frame_parms.nb_antennas_rx == 1 || N_ports == 1) { + return 0; + } else if( !(ue->frame_parms.nb_antennas_rx == 2 && N_ports == 2) ) { + LOG_W(NR_PHY, "Rank indicator computation is not implemented for %i x %i system\n", + ue->frame_parms.nb_antennas_rx, N_ports); + return -1; + } + + /* Example 2x2: Hh x H = + * | conjch00 conjch10 | x | ch00 ch01 | = | conjch00*ch00+conjch10*ch10 conjch00*ch01+conjch10*ch11 | + * | conjch01 conjch11 | | ch10 ch11 | | conjch01*ch00+conjch11*ch10 conjch01*ch01+conjch11*ch11 | + */ + + int32_t csi_rs_estimated_conjch_ch[frame_parms->nb_antennas_rx][N_ports][frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); + int32_t csi_rs_estimated_A_MF[N_ports][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); + int32_t csi_rs_estimated_A_MF_sq[N_ports][N_ports][frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); + int32_t csi_rs_estimated_determ_fin[frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); + int32_t csi_rs_estimated_numer_fin[frame_parms->ofdm_symbol_size] __attribute__((aligned(32))); + + const uint8_t sum_shift = 1; // log2(2x2) = 2, which is a shift of 1 bit + + for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { + + if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) { + continue; + } + uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; + + for (int ant_rx_conjch = 0; ant_rx_conjch < frame_parms->nb_antennas_rx; ant_rx_conjch++) { + for(uint16_t port_tx_conjch = 0; port_tx_conjch < N_ports; port_tx_conjch++) { + for (int ant_rx_ch = 0; ant_rx_ch < frame_parms->nb_antennas_rx; ant_rx_ch++) { + for(uint16_t port_tx_ch = 0; port_tx_ch < N_ports; port_tx_ch++) { + + // conjch x ch computation + nr_conjch0_mult_ch1(&csi_rs_estimated_channel_freq[ant_rx_conjch][port_tx_conjch][k], + &csi_rs_estimated_channel_freq[ant_rx_ch][port_tx_ch][k], + &csi_rs_estimated_conjch_ch[ant_rx_conjch][port_tx_conjch][ant_rx_ch][port_tx_ch][k], + 1, + log2_maxh); + + // construct Hh x H elements + if(ant_rx_conjch == ant_rx_ch) { + nr_a_sum_b((__m128i *)&csi_rs_estimated_A_MF[port_tx_conjch][port_tx_ch][k], + (__m128i *)&csi_rs_estimated_conjch_ch[ant_rx_conjch][port_tx_conjch][ant_rx_ch][port_tx_ch][k], + 1); + } + } + } + } + } + + // compute the determinant of A_MF (denominator) + nr_det_A_MF_2x2(&csi_rs_estimated_A_MF[0][0][k], + &csi_rs_estimated_A_MF[0][1][k], + &csi_rs_estimated_A_MF[1][0][k], + &csi_rs_estimated_A_MF[1][1][k], + &csi_rs_estimated_determ_fin[k], + 1); + + // compute the square of A_MF (numerator) + nr_squared_matrix_element(&csi_rs_estimated_A_MF[0][0][k], &csi_rs_estimated_A_MF_sq[0][0][k], 1); + nr_squared_matrix_element(&csi_rs_estimated_A_MF[0][1][k], &csi_rs_estimated_A_MF_sq[0][1][k], 1); + nr_squared_matrix_element(&csi_rs_estimated_A_MF[1][0][k], &csi_rs_estimated_A_MF_sq[1][0][k], 1); + nr_squared_matrix_element(&csi_rs_estimated_A_MF[1][1][k], &csi_rs_estimated_A_MF_sq[1][1][k], 1); + nr_numer_2x2(&csi_rs_estimated_A_MF_sq[0][0][k], + &csi_rs_estimated_A_MF_sq[0][1][k], + &csi_rs_estimated_A_MF_sq[1][0][k], + &csi_rs_estimated_A_MF_sq[1][1][k], + &csi_rs_estimated_numer_fin[k], + 1); + +#ifdef NR_CSIRS_DEBUG + for(uint16_t port_tx_conjch = 0; port_tx_conjch < N_ports; port_tx_conjch++) { + for(uint16_t port_tx_ch = 0; port_tx_ch < N_ports; port_tx_ch++) { + c16_t *csi_rs_estimated_A_MF_k = (c16_t *) &csi_rs_estimated_A_MF[port_tx_conjch][port_tx_ch][k]; + LOG_I(NR_PHY, "(%i) csi_rs_estimated_A_MF[%i][%i] = (%i, %i)\n", + k, port_tx_conjch, port_tx_ch, csi_rs_estimated_A_MF_k->r, csi_rs_estimated_A_MF_k->i); + c16_t *csi_rs_estimated_A_MF_sq_k = (c16_t *) &csi_rs_estimated_A_MF_sq[port_tx_conjch][port_tx_ch][k]; + LOG_I(NR_PHY, "(%i) csi_rs_estimated_A_MF_sq[%i][%i] = (%i, %i)\n", + k, port_tx_conjch, port_tx_ch, csi_rs_estimated_A_MF_sq_k->r, csi_rs_estimated_A_MF_sq_k->i); + } + } + LOG_I(NR_PHY, "(%i) csi_rs_estimated_determ_fin = %i\n", k, csi_rs_estimated_determ_fin[k]); + LOG_I(NR_PHY, "(%i) csi_rs_estimated_numer_fin = %i\n", k, csi_rs_estimated_numer_fin[k]>>sum_shift); +#endif + + // compute the conditional number + for (int sc_idx=0; sc_idx < NR_NB_SC_PER_RB; sc_idx++) { + int8_t csi_rs_estimated_denum_db = dB_fixed(csi_rs_estimated_determ_fin[k + sc_idx]); + int8_t csi_rs_estimated_numer_db = dB_fixed(csi_rs_estimated_numer_fin[k + sc_idx]>>sum_shift); + int8_t cond_db = csi_rs_estimated_numer_db - csi_rs_estimated_denum_db; + +#ifdef NR_CSIRS_DEBUG + LOG_I(NR_PHY, "csi_rs_estimated_denum_db = %i\n", csi_rs_estimated_denum_db); + LOG_I(NR_PHY, "csi_rs_estimated_numer_db = %i\n", csi_rs_estimated_numer_db); + LOG_I(NR_PHY, "cond_db = %i\n", cond_db); +#endif + + if (cond_db < cond_dB_threshold) { + count++; + } else { + count--; + } + } + } + + // conditional number is lower than cond_dB_threshold in half on more REs + if (count > 0) { + *rank_indicator = 1; + } + +#ifdef NR_CSIRS_DEBUG + LOG_I(NR_PHY, "count = %i\n", count); + LOG_I(NR_PHY, "rank = %i\n", (*rank_indicator)+1); +#endif + + return 0; +} + +int nr_csi_rs_pmi_estimation(const PHY_VARS_NR_UE *ue, + const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu, + const nr_csi_info_t *nr_csi_info, + const uint8_t N_ports, + const int32_t csi_rs_estimated_channel_freq[][N_ports][ue->frame_parms.ofdm_symbol_size], + const uint32_t interference_plus_noise_power, + const uint8_t rank_indicator, + const int16_t log2_re, + uint8_t *i1, + uint8_t *i2, + uint32_t *precoded_sinr_dB) { + + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + memset(i1,0,3*sizeof(uint8_t)); + i2[0] = 0; + + // i1 is a three-element vector in the form of [i11 i12 i13], when CodebookType is specified as 'Type1SinglePanel'. + // Note that i13 is not applicable when the number of transmission layers is one of {1, 5, 6, 7, 8}. + // i2, for 'Type1SinglePanel' codebook type, it is a scalar when PMIMode is specified as 'wideband', and when PMIMode + // is specified as 'subband' or when PRGSize, the length of the i2 vector equals to the number of subbands or PRGs. + // Note that when the number of CSI-RS ports is 2, the applicable codebook type is 'Type1SinglePanel'. In this case, + // the precoding matrix is obtained by a single index (i2 field here) based on TS 38.214 Table 5.2.2.2.1-1. + // The first column is applicable if the UE is reporting a Rank = 1, whereas the second column is applicable if the + // UE is reporting a Rank = 2. + + if(N_ports == 1 || interference_plus_noise_power == 0) { + return 0; + } + + if(rank_indicator == 0 || rank_indicator == 1) { + + int32_t sum_re[4] = {0}; + int32_t sum_im[4] = {0}; + int32_t sum2_re[4] = {0}; + int32_t sum2_im[4] = {0}; + int32_t tested_precoded_sinr[4] = {0}; + + for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) { + + if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) { + continue; + } + uint16_t k = (frame_parms->first_carrier_offset + rb * NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; + + for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { + + c16_t *csi_rs_estimated_channel_p0 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][0][k]; + c16_t *csi_rs_estimated_channel_p1 = (c16_t *) &csi_rs_estimated_channel_freq[ant_rx][1][k]; + + // H_p0 + 1*H_p1 = (H_p0_re + H_p1_re) + 1j*(H_p0_im + H_p1_im) + sum_re[0] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r); + sum_im[0] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i); + sum2_re[0] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->r))>>log2_re; + sum2_im[0] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->i))>>log2_re; + + // H_p0 + 1j*H_p1 = (H_p0_re - H_p1_im) + 1j*(H_p0_im + H_p1_re) + sum_re[1] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i); + sum_im[1] += (csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r); + sum2_re[1] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->i))>>log2_re; + sum2_im[1] += ((csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i+csi_rs_estimated_channel_p1->r))>>log2_re; + + // H_p0 - 1*H_p1 = (H_p0_re - H_p1_re) + 1j*(H_p0_im - H_p1_im) + sum_re[2] += (csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r); + sum_im[2] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i); + sum2_re[2] += ((csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->r-csi_rs_estimated_channel_p1->r))>>log2_re; + sum2_im[2] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->i))>>log2_re; + + // H_p0 - 1j*H_p1 = (H_p0_re + H_p1_im) + 1j*(H_p0_im - H_p1_re) + sum_re[3] += (csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i); + sum_im[3] += (csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r); + sum2_re[3] += ((csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i)*(csi_rs_estimated_channel_p0->r+csi_rs_estimated_channel_p1->i))>>log2_re; + sum2_im[3] += ((csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r)*(csi_rs_estimated_channel_p0->i-csi_rs_estimated_channel_p1->r))>>log2_re; + } + } + + // We should perform >>nr_csi_info->log2_re here for all terms, but since sum2_re and sum2_im can be high values, + // we performed this above. + for(int p = 0; p<4; p++) { + int32_t power_re = sum2_re[p] - (sum_re[p]>>log2_re)*(sum_re[p]>>log2_re); + int32_t power_im = sum2_im[p] - (sum_im[p]>>log2_re)*(sum_im[p]>>log2_re); + tested_precoded_sinr[p] = (power_re+power_im)/(int32_t)interference_plus_noise_power; + } + + if(rank_indicator == 0) { + for(int tested_i2 = 0; tested_i2 < 4; tested_i2++) { + if(tested_precoded_sinr[tested_i2] > tested_precoded_sinr[i2[0]]) { + i2[0] = tested_i2; + } + } + *precoded_sinr_dB = dB_fixed(tested_precoded_sinr[i2[0]]); + } else { + i2[0] = tested_precoded_sinr[0]+tested_precoded_sinr[2] > tested_precoded_sinr[1]+tested_precoded_sinr[3] ? 0 : 1; + *precoded_sinr_dB = dB_fixed((tested_precoded_sinr[i2[0]] + tested_precoded_sinr[i2[0]+2])>>1); + } + + } else { + LOG_W(NR_PHY, "PMI computation is not implemented for rank indicator %i\n", rank_indicator+1); + return -1; + } + + return 0; +} + +int nr_csi_rs_cqi_estimation(const uint32_t precoded_sinr, + uint8_t *cqi) { + + *cqi = 0; + + // Default SINR table for an AWGN channel for SISO scenario, considering 0.1 BLER condition and TS 38.214 Table 5.2.2.1-2 + if(precoded_sinr>0 && precoded_sinr<=2) { + *cqi = 4; + } else if(precoded_sinr==3) { + *cqi = 5; + } else if(precoded_sinr>3 && precoded_sinr<=5) { + *cqi = 6; + } else if(precoded_sinr>5 && precoded_sinr<=7) { + *cqi = 7; + } else if(precoded_sinr>7 && precoded_sinr<=9) { + *cqi = 8; + } else if(precoded_sinr==10) { + *cqi = 9; + } else if(precoded_sinr>10 && precoded_sinr<=12) { + *cqi = 10; + } else if(precoded_sinr>12 && precoded_sinr<=15) { + *cqi = 11; + } else if(precoded_sinr==16) { + *cqi = 12; + } else if(precoded_sinr>16 && precoded_sinr<=18) { + *cqi = 13; + } else if(precoded_sinr==19) { + *cqi = 14; + } else if(precoded_sinr>19) { + *cqi = 15; + } + + return 0; +} + +int nr_csi_im_power_estimation(const PHY_VARS_NR_UE *ue, + const UE_nr_rxtx_proc_t *proc, + const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu, + uint32_t *interference_plus_noise_power) { + + int32_t **rxdataF = ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF; + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + + const uint16_t end_rb = csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs > csiim_config_pdu->bwp_size ? + csiim_config_pdu->bwp_size : csiim_config_pdu->start_rb + csiim_config_pdu->nr_of_rbs; + + int32_t count = 0; + int32_t sum_re = 0; + int32_t sum_im = 0; + int32_t sum2_re = 0; + int32_t sum2_im = 0; + + int l_csiim[4] = {-1, -1, -1, -1}; + + for(int symb_idx = 0; symb_idx < 4; symb_idx++) { + + uint8_t symb = csiim_config_pdu->l_csiim[symb_idx]; + bool done = false; + for (int symb_idx2 = 0; symb_idx2 < symb_idx; symb_idx2++) { + if (l_csiim[symb_idx2] == symb) { + done = true; + } + } + + if (done) { + continue; + } + + l_csiim[symb_idx] = symb; + uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size; + + for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) { + + c16_t *rx_signal = (c16_t*)&rxdataF[ant_rx][symbol_offset]; + + for (int rb = csiim_config_pdu->start_rb; rb < end_rb; rb++) { + + uint16_t sc0_offset = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size; + + for (int sc_idx = 0; sc_idx<4; sc_idx++) { + + uint16_t sc = sc0_offset + csiim_config_pdu->k_csiim[sc_idx]; + +#ifdef NR_CSIIM_DEBUG + LOG_I(NR_PHY, "(ant_rx %i, sc %i) real %i, imag %i\n", ant_rx, rb, rx_signal[sc].r, rx_signal[sc].i); +#endif + + sum_re += rx_signal[sc].r; + sum_im += rx_signal[sc].i; + sum2_re += rx_signal[sc].r*rx_signal[sc].r; + sum2_im += rx_signal[sc].i*rx_signal[sc].i; + count++; + } + } + } + } + + int32_t power_re = sum2_re/count - (sum_re/count)*(sum_re/count); + int32_t power_im = sum2_im/count - (sum_im/count)*(sum_im/count); + + *interference_plus_noise_power = power_re + power_im; + +#ifdef NR_CSIIM_DEBUG + LOG_I(NR_PHY, "interference_plus_noise_power based on CSI-IM = %i\n", *interference_plus_noise_power); +#endif + + return 0; +} + int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) { + + if(!ue->csiim_vars[gNB_id]->active) { + return -1; + } + + const fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu = (fapi_nr_dl_config_csiim_pdu_rel15_t*)&ue->csiim_vars[gNB_id]->csiim_config_pdu; + +#ifdef NR_CSIIM_DEBUG + LOG_I(NR_PHY, "csiim_config_pdu->bwp_size = %i\n", csiim_config_pdu->bwp_size); + LOG_I(NR_PHY, "csiim_config_pdu->bwp_start = %i\n", csiim_config_pdu->bwp_start); + LOG_I(NR_PHY, "csiim_config_pdu->subcarrier_spacing = %i\n", csiim_config_pdu->subcarrier_spacing); + LOG_I(NR_PHY, "csiim_config_pdu->start_rb = %i\n", csiim_config_pdu->start_rb); + LOG_I(NR_PHY, "csiim_config_pdu->nr_of_rbs = %i\n", csiim_config_pdu->nr_of_rbs); + LOG_I(NR_PHY, "csiim_config_pdu->k_csiim = %i.%i.%i.%i\n", csiim_config_pdu->k_csiim[0], csiim_config_pdu->k_csiim[1], csiim_config_pdu->k_csiim[2], csiim_config_pdu->k_csiim[3]); + LOG_I(NR_PHY, "csiim_config_pdu->l_csiim = %i.%i.%i.%i\n", csiim_config_pdu->l_csiim[0], csiim_config_pdu->l_csiim[1], csiim_config_pdu->l_csiim[2], csiim_config_pdu->l_csiim[3]); +#endif + + nr_csi_im_power_estimation(ue, proc, csiim_config_pdu, &ue->nr_csi_info->interference_plus_noise_power); + ue->nr_csi_info->csi_im_meas_computed = true; + return 0; } @@ -336,7 +829,7 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t return -1; } - fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = (fapi_nr_dl_config_csirs_pdu_rel15_t*)&ue->csirs_vars[gNB_id]->csirs_config_pdu; + const fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = (fapi_nr_dl_config_csirs_pdu_rel15_t*)&ue->csirs_vars[gNB_id]->csirs_config_pdu; #ifdef NR_CSIRS_DEBUG LOG_I(NR_PHY, "csirs_config_pdu->subcarrier_spacing = %i\n", csirs_config_pdu->subcarrier_spacing); @@ -355,26 +848,122 @@ int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t LOG_I(NR_PHY, "csirs_config_pdu->power_control_offset_ss = %i\n", csirs_config_pdu->power_control_offset_ss); #endif - nr_generate_csi_rs(ue->frame_parms, - ue->nr_csi_rs_info->csi_rs_generated_signal, + const NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; + int32_t csi_rs_received_signal[frame_parms->nb_antennas_rx][frame_parms->samples_per_slot_wCP]; + uint8_t N_cdm_groups = 0; + uint8_t CDM_group_size = 0; + uint8_t k_prime = 0; + uint8_t l_prime = 0; + uint8_t N_ports = 0; + uint8_t j_cdm[16]; + uint8_t k_overline[16]; + uint8_t l_overline[16]; + int16_t log2_re = 0; + int16_t log2_maxh = 0; + uint32_t rsrp = 0; + int rsrp_dBm = 0; + uint32_t noise_power = 0; + uint8_t rank_indicator = 0; + uint32_t precoded_sinr_dB = 0; + uint8_t cqi = 0; + uint8_t i1[3]; + uint8_t i2[1]; + + nr_generate_csi_rs(frame_parms, + ue->nr_csi_info->csi_rs_generated_signal, AMP, - ue->nr_csi_rs_info, + ue->nr_csi_info, (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *) csirs_config_pdu, - proc->nr_slot_rx); + proc->nr_slot_rx, + &N_cdm_groups, + &CDM_group_size, + &k_prime, + &l_prime, + &N_ports, + j_cdm, + k_overline, + l_overline); + + int32_t csi_rs_ls_estimated_channel[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size]; + int32_t csi_rs_estimated_channel_freq[frame_parms->nb_antennas_rx][N_ports][frame_parms->ofdm_symbol_size]; nr_get_csi_rs_signal(ue, proc, csirs_config_pdu, - ue->nr_csi_rs_info, - ue->nr_csi_rs_info->csi_rs_received_signal); + ue->nr_csi_info, + N_cdm_groups, + CDM_group_size, + k_prime, + l_prime, + j_cdm, + k_overline, + l_overline, + csi_rs_received_signal, + &rsrp, + &rsrp_dBm); nr_csi_rs_channel_estimation(ue, proc, csirs_config_pdu, - ue->nr_csi_rs_info, - ue->nr_csi_rs_info->csi_rs_generated_signal, - ue->nr_csi_rs_info->csi_rs_received_signal, - ue->nr_csi_rs_info->csi_rs_estimated_channel_freq, - ue->nr_csi_rs_info->noise_power); + ue->nr_csi_info, + (const int32_t **) ue->nr_csi_info->csi_rs_generated_signal, + csi_rs_received_signal, + N_cdm_groups, + CDM_group_size, + k_prime, + l_prime, + N_ports, + j_cdm, + k_overline, + l_overline, + csi_rs_ls_estimated_channel, + csi_rs_estimated_channel_freq, + &log2_re, + &log2_maxh, + &noise_power); + + nr_csi_rs_ri_estimation(ue, + csirs_config_pdu, + ue->nr_csi_info, + N_ports, + csi_rs_estimated_channel_freq, + log2_maxh, + &rank_indicator); + + nr_csi_rs_pmi_estimation(ue, + csirs_config_pdu, + ue->nr_csi_info, + N_ports, + csi_rs_estimated_channel_freq, + ue->nr_csi_info->csi_im_meas_computed ? ue->nr_csi_info->interference_plus_noise_power : noise_power, + rank_indicator, + log2_re, + i1, + i2, + &precoded_sinr_dB); + + nr_csi_rs_cqi_estimation(precoded_sinr_dB, &cqi); + + LOG_I(NR_PHY, "RSRP = %i dBm, RI = %i, i1 = %i.%i.%i, i2 = %i, SINR = %i dB, CQI = %i\n", + rsrp_dBm, rank_indicator+1, i1[0], i1[1], i1[2], i2[0], precoded_sinr_dB, cqi); + + // Send CSI measurements to MAC + fapi_nr_csirs_measurements_t csirs_measurements; + csirs_measurements.rsrp = rsrp; + csirs_measurements.rsrp_dBm = rsrp_dBm; + csirs_measurements.rank_indicator = rank_indicator; + csirs_measurements.i1 = *i1; + csirs_measurements.i2 = *i2; + csirs_measurements.cqi = cqi; + nr_downlink_indication_t dl_indication; + fapi_nr_rx_indication_t *rx_ind = calloc(sizeof(*rx_ind),1); + nr_fill_dl_indication(&dl_indication, NULL, rx_ind, proc, ue, gNB_id, NULL); + nr_fill_rx_indication(rx_ind, FAPI_NR_CSIRS_IND, gNB_id, ue, NULL, NULL, 1, proc, (void *)&csirs_measurements); + if (ue->if_inst && ue->if_inst->dl_indication) { + ue->if_inst->dl_indication(&dl_indication, NULL); + } else { + free(rx_ind); + } + return 0; } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 403f016e79bcc571ab70125306e398e929bf5f26..1635c8bba9c30b69a948b7ad94818b3aa77f1386 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -140,7 +140,6 @@ NR_UE_DLSCH_t *new_nr_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint dlsch->Mdlharq = Mdlharq; dlsch->number_harq_processes_for_pdsch = Mdlharq; dlsch->Nsoft = Nsoft; - dlsch->Mlimit = 4; dlsch->max_ldpc_iterations = max_ldpc_iterations; for (int i=0; i<Mdlharq; i++) { @@ -222,7 +221,6 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n", // phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round); harq_process->status = SCH_IDLE; - harq_process->DLround = 0; harq_process->ack = 1; //LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d)\n", @@ -237,11 +235,6 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool //LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", // phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); harq_process->ack = 0; - if (harq_process->DLround >= dlsch->Mlimit) { - harq_process->status = SCH_IDLE; - harq_process->DLround = 0; - phy_vars_ue->dl_stats[4]++; - } //if(is_crnti) { // LOG_D(PHY,"[UE %d] DLSCH: Setting NACK for nr_slot_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", @@ -496,8 +489,6 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, } */ nb_rb = harq_process->nb_rb; - harq_process->trials[harq_process->DLround]++; - A = harq_process->TBS; ret = dlsch->max_ldpc_iterations + 1; dlsch->last_iteration_cnt = ret; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index eb43d805252d0d42964d337d665e344d720eaea0..6728f0260c093cdaacee71d757bbcee9c5c0e5d7 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -466,88 +466,87 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, if (cpumeas(CPUMEAS_GETSTATE)) LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: Channel Combine and zero forcing %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); - start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); + start_meas(&ue->generic_stat_bis[proc->thread_id][slot]); /* Store the valid DL RE's */ - pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = nb_re_pdsch; + pdsch_vars[gNB_id]->dl_valid_re[symbol-1] = nb_re_pdsch; - if(dlsch0_harq->status == ACTIVE) { - startSymbIdx = dlsch0_harq->start_symbol; - nbSymb = dlsch0_harq->nb_symbols; - pduBitmap = dlsch0_harq->pduBitmap; - } - if(dlsch1_harq) { - startSymbIdx = dlsch1_harq->start_symbol; - nbSymb = dlsch1_harq->nb_symbols; - pduBitmap = dlsch1_harq->pduBitmap; - } + if(dlsch0_harq->status == ACTIVE) { + startSymbIdx = dlsch0_harq->start_symbol; + nbSymb = dlsch0_harq->nb_symbols; + pduBitmap = dlsch0_harq->pduBitmap; + } + if(dlsch1_harq) { + startSymbIdx = dlsch1_harq->start_symbol; + nbSymb = dlsch1_harq->nb_symbols; + pduBitmap = dlsch1_harq->pduBitmap; + } - /* Check for PTRS bitmap and process it respectively */ - if((pduBitmap & 0x1) && (type == PDSCH)) { - nr_pdsch_ptrs_processing(ue, - pdsch_vars, - frame_parms, - dlsch0_harq, - dlsch1_harq, - gNB_id, - nr_slot_rx, - symbol, - (nb_rb_pdsch*12), - dlsch[0]->rnti,rx_type); - pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol]; - } + /* Check for PTRS bitmap and process it respectively */ + if((pduBitmap & 0x1) && (type == PDSCH)) { + nr_pdsch_ptrs_processing(ue, + pdsch_vars, + frame_parms, + dlsch0_harq, + dlsch1_harq, + gNB_id, + nr_slot_rx, + symbol, + (nb_rb_pdsch*12), + dlsch[0]->rnti,rx_type); + pdsch_vars[gNB_id]->dl_valid_re[symbol-1] -= pdsch_vars[gNB_id]->ptrs_re_per_slot[0][symbol]; + } - /* at last symbol in a slot calculate LLR's for whole slot */ - if(symbol == (startSymbIdx + nbSymb -1)) { - for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) { - /* re evaluating the first symbol flag as LLR's are done in symbol loop */ - if(i == startSymbIdx && i < 3) { - first_symbol_flag =1; - } - else { - first_symbol_flag=0; - } - /* Calculate LLR's for each symbol */ - nr_dlsch_llr(pdsch_vars, frame_parms, - rxdataF_comp_ptr, dl_ch_mag_ptr, - dlsch0_harq, dlsch1_harq, - rx_type, harq_pid, - gNB_id, gNB_id_i, - first_symbol_flag, - i, nb_rb_pdsch, - codeword_TB0, codeword_TB1, - pdsch_vars[gNB_id]->dl_valid_re[i-1], - nr_slot_rx, beamforming_mode); + /* at last symbol in a slot calculate LLR's for whole slot */ + if(symbol == (startSymbIdx + nbSymb -1)) { + for(uint8_t i =startSymbIdx; i < (startSymbIdx+nbSymb);i++) { + /* re evaluating the first symbol flag as LLR's are done in symbol loop */ + if(i == startSymbIdx && i < 3) { + first_symbol_flag =1; } - - int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType; - uint8_t nb_re_dmrs; - uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos); - if (dmrs_type==NFAPI_NR_DMRS_TYPE1) { - nb_re_dmrs = 6*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups; - } else { - nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups; + else { + first_symbol_flag=0; } - dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb, - dlsch[0]->harq_processes[harq_pid]->nb_symbols, - nb_re_dmrs, - dmrs_len, - dlsch[0]->harq_processes[harq_pid]->Qm, - dlsch[0]->harq_processes[harq_pid]->Nl); - nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr, - dlsch[0]->harq_processes[harq_pid]->Nl, - dlsch[0]->harq_processes[harq_pid]->Qm, - dlsch[0]->harq_processes[harq_pid]->G, - codeword_TB0, - codeword_TB1, - pdsch_vars[gNB_id]->layer_llr); + /* Calculate LLR's for each symbol */ + nr_dlsch_llr(pdsch_vars, frame_parms, + rxdataF_comp_ptr, dl_ch_mag_ptr, + dlsch0_harq, dlsch1_harq, + rx_type, harq_pid, + gNB_id, gNB_id_i, + first_symbol_flag, + i, nb_rb_pdsch, + codeword_TB0, codeword_TB1, + pdsch_vars[gNB_id]->dl_valid_re[i-1], + nr_slot_rx, beamforming_mode); + } + int dmrs_type = dlsch[0]->harq_processes[harq_pid]->dmrsConfigType; + uint8_t nb_re_dmrs; + uint16_t dmrs_len = get_num_dmrs(dlsch[0]->harq_processes[harq_pid]->dlDmrsSymbPos); + if (dmrs_type==NFAPI_NR_DMRS_TYPE1) { + nb_re_dmrs = 6*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups; + } else { + nb_re_dmrs = 4*dlsch[0]->harq_processes[harq_pid]->n_dmrs_cdm_groups; } + dlsch[0]->harq_processes[harq_pid]->G = nr_get_G(dlsch[0]->harq_processes[harq_pid]->nb_rb, + dlsch[0]->harq_processes[harq_pid]->nb_symbols, + nb_re_dmrs, + dmrs_len, + dlsch[0]->harq_processes[harq_pid]->Qm, + dlsch[0]->harq_processes[harq_pid]->Nl); + nr_dlsch_layer_demapping(pdsch_vars[gNB_id]->llr, + dlsch[0]->harq_processes[harq_pid]->Nl, + dlsch[0]->harq_processes[harq_pid]->Qm, + dlsch[0]->harq_processes[harq_pid]->G, + codeword_TB0, + codeword_TB1, + pdsch_vars[gNB_id]->layer_llr); + } - stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); - if (cpumeas(CPUMEAS_GETSTATE)) - LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); + stop_meas(&ue->generic_stat_bis[proc->thread_id][slot]); + if (cpumeas(CPUMEAS_GETSTATE)) + LOG_D(PHY, "[AbsSFN %u.%d] Slot%d Symbol %d: LLR Computation %5.2f \n",frame,nr_slot_rx,slot,symbol,ue->generic_stat_bis[proc->thread_id][slot].p_time/(cpuf*1000.0)); -// Please keep it: useful for debugging + // Please keep it: useful for debugging #ifdef DEBUG_PDSCH_RX char filename[50]; uint8_t aa = 0; diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c index 5f3af5bb3958aa5b80f3338b06d503ffb4c08091..ea7bde5377ffc9eb10aed4f776849348c24ab6f5 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c @@ -362,7 +362,7 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc, nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]); } - nr_init_csi_rs(fp, ue->nr_csi_rs_info->nr_gold_csi_rs, fp->Nid_cell); + nr_init_csi_rs(fp, ue->nr_csi_info->nr_gold_csi_rs, fp->Nid_cell); // initialize the pusch dmrs for (int i=0; i<NR_NB_NSCID; i++) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 9e680bf2271b6a748ae94130ec02f3054595f0fe..6d99ac9b8c234c7562aa00dcf912d3c32968a966 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -855,10 +855,6 @@ void construct_HhH_elements(int *ch0conj_ch0, int32_t *after_mf_11, unsigned short nb_rb); -void squared_matrix_element(int32_t *Hh_h_00, - int32_t *Hh_h_00_sq, - unsigned short nb_rb); - void dlsch_channel_level_TM34_meas(int *ch00, int *ch01, int *ch10, @@ -885,19 +881,15 @@ void nr_dlsch_detection_mrc(int **rxdataF_comp, unsigned short nb_rb, int length); -void det_HhH(int32_t *after_mf_00, - int32_t *after_mf_01, - int32_t *after_mf_10, - int32_t *after_mf_11, - int32_t *det_fin_128, - unsigned short nb_rb); - -void numer(int32_t *Hh_h_00_sq, - int32_t *Hh_h_01_sq, - int32_t *Hh_h_10_sq, - int32_t *Hh_h_11_sq, - int32_t *num_fin, - unsigned short nb_rb); +void nr_conjch0_mult_ch1(int *ch0, + int *ch1, + int32_t *ch0conj_ch1, + unsigned short nb_rb, + unsigned char output_shift0); + +void nr_a_sum_b(__m128i *input_x, + __m128i *input_y, + unsigned short nb_rb); uint8_t rank_estimation_tm3_tm4(int *dl_ch_estimates_00, int *dl_ch_estimates_01, diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 7ecba40c3a878bf5365783e270eb449f5f8c0726..96f31a1624be335f01edb38492edc5ad05dd34d5 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -161,15 +161,13 @@ typedef struct { //uint8_t num_cba_dci[10]; /// allocated CBA RNTI //uint16_t cba_rnti[4];//NUM_MAX_CBA_GROUP]; - /// UL max-harq-retransmission - uint16_t Mlimit; } NR_UE_ULSCH_t; typedef struct { /// Indicator of first reception uint8_t first_rx; /// Last Ndi received for this process on DCI (used for C-RNTI only) - uint8_t DCINdi; + uint8_t Ndi; /// DLSCH status flag indicating SCH_status_t status; /// Transport block size @@ -241,10 +239,6 @@ typedef struct { vrb_t vrb_type; /// downlink power offset field uint8_t dl_power_off; - /// trials per round statistics - uint32_t trials[8]; - /// error statistics per round - uint32_t errors[8]; /// codeword this transport block is mapped to uint8_t codeword; /// HARQ-ACKs @@ -311,9 +305,7 @@ typedef struct { /// Maximum number of LDPC iterations uint8_t max_ldpc_iterations; /// number of iterations used in last turbo decoding - uint8_t last_iteration_cnt; - /// Maximum number of HARQ rounds - uint8_t Mlimit; + uint8_t last_iteration_cnt; } NR_UE_DLSCH_t; typedef enum {format0_0, @@ -342,7 +334,7 @@ typedef struct { /// Position of first CCE of the dci int firstCCE; /// flag to indicate that this is a RA response - boolean_t ra_flag; + bool ra_flag; /// rnti rnti_t rnti; /// rnti type diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index d09f2554cc1465b2c68f824a320d234b77867702..ef952b01529a890764a7f81948757f7f533fe229 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -130,10 +130,6 @@ NR_UE_ULSCH_t *new_nr_ue_ulsch(uint16_t N_RB_UL, int number_of_harq_pids, NR_DL_ memset(ulsch, 0, sizeof(*ulsch)); ulsch->number_harq_processes_for_pusch = NR_MAX_ULSCH_HARQ_PROCESSES; - ulsch->Mlimit = 4; // maximum harq retransmissions - - //for (i=0; i<10; i++) - //ulsch->harq_ids[i] = 0; for (int i = 0; i < number_of_harq_pids; i++) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index a07a19d085f43c0628416d699595fdaf09126d43..eaeffd08099a987c9c848d9043fb5a862311dace 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -597,17 +597,15 @@ uint8_t nr_ue_pusch_common_procedures(PHY_VARS_NR_UE *UE, int symb_offset = (slot%frame_parms->slots_per_subframe)*frame_parms->symbols_per_slot; for(ap = 0; ap < n_antenna_ports; ap++) { for (int s=0;s<NR_NUMBER_OF_SYMBOLS_PER_SLOT;s++){ - - LOG_D(PHY,"In %s: rotating txdataF symbol %d (%d) => (%d.%d)\n", - __FUNCTION__, - s, - s + symb_offset, - frame_parms->symbol_rotation[1][2 * (s + symb_offset)], - frame_parms->symbol_rotation[1][1 + (2 * (s + symb_offset))]); - - rotate_cpx_vector((int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], - &frame_parms->symbol_rotation[1][2 * (s + symb_offset)], - (int16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], + c16_t rot=((c16_t*)frame_parms->symbol_rotation[1])[s + symb_offset]; + LOG_D(PHY,"rotating txdataF symbol %d (%d) => (%d.%d)\n", + s, + s + symb_offset, + rot.r, rot.i); + + rotate_cpx_vector((c16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], + &rot, + (c16_t *)&txdataF[ap][frame_parms->ofdm_symbol_size * s], frame_parms->ofdm_symbol_size, 15); } diff --git a/openair1/PHY/TOOLS/calibration_scope.c b/openair1/PHY/TOOLS/calibration_scope.c index da1acb517570e78fa352fcbb289def26fcc67064..d3397b033f1da10d07fd343a7f6fa951392b1874 100644 --- a/openair1/PHY/TOOLS/calibration_scope.c +++ b/openair1/PHY/TOOLS/calibration_scope.c @@ -34,7 +34,7 @@ typedef struct OAIgraph { int h; int waterFallh; double *waterFallAvg; - boolean_t initDone; + bool initDone; int iteration; void (*funct) (struct OAIgraph *graph, calibData_t *); } OAIgraph_t; @@ -159,7 +159,7 @@ static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len *y=old_y; } -static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, boolean_t NoAutoScale) { +static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, bool NoAutoScale) { fl_redraw_object(graph->graph); if ( NoAutoScale && graph->iteration%NoAutoScale == 0) { diff --git a/openair1/PHY/TOOLS/cmult_sv.c b/openair1/PHY/TOOLS/cmult_sv.c index dc57964ca52a60ff699ff0d0066c5376512ce5ec..a9d502b9eb1b5d7a9ff0259030af7324389394c7 100644 --- a/openair1/PHY/TOOLS/cmult_sv.c +++ b/openair1/PHY/TOOLS/cmult_sv.c @@ -144,207 +144,10 @@ void multadd_real_four_symbols_vector_complex_scalar(int16_t *x, _m_empty(); } - -/* -int rotate_cpx_vector(int16_t *x, - int16_t *alpha, - int16_t *y, - uint32_t N, - uint16_t output_shift, - uint8_t format) -{ - // Multiply elementwise two complex vectors of N elements - // x - input 1 in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)| - // We assume x1 with a dynamic of 15 bit maximum - // - // alpha - input 2 in the format |Re0 Im0| - // We assume x2 with a dynamic of 15 bit maximum - // - // y - output in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)| - // - // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; - // - // output_shift - shift at output to return in Q1.15 - // format - 0 means alpha is in shuffled format, 1 means x is in shuffled format - - uint32_t i; // loop counter - - register __m128i m0,m1; - - - - __m128i *x_128; - __m128i *y_128; - - - shift = _mm_cvtsi32_si128(output_shift); - x_128 = (__m128i *)&x[0]; - - if (format==0) { // alpha is in shuffled format for complex multiply - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = -alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[1]; - ((int16_t *)&alpha_128)[3] = alpha[0]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = -alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[1]; - ((int16_t *)&alpha_128)[7] = alpha[0]; - } else { // input is in shuffled format for complex multiply - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[0]; - ((int16_t *)&alpha_128)[3] = alpha[1]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[0]; - ((int16_t *)&alpha_128)[7] = alpha[1]; - } - - y_128 = (__m128i *)&y[0]; - - // _mm_empty(); - // return(0); - - // we compute 4 cpx multiply for each loop - for(i=0; i<(N>>3); i++) { - - m0 = _mm_madd_epi16(x_128[0],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0] - m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude - m1=m0; - m0 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im] - y_128[0] = _mm_unpacklo_epi32(m0,m0); // 1- pack in a 128 bit register [re im re im] - m0 = _mm_madd_epi16(x_128[1],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0] - m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude - m1 = m0; - m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im] - y_128[1] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im] - m0 = _mm_madd_epi16(x_128[2],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0] - m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude - m1 = m0; - m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im] - y_128[2] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im] - m0 = _mm_madd_epi16(x_128[3],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0] - m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude - m1 = m0; - m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im] - y_128[3] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im] - if (format==1) { // Put output in proper format (Re,-Im,Im,Re), shuffle = (0,1,3,2) = 0x1e - - y_128[0] = _mm_shufflelo_epi16(y_128[0],0x1e); - y_128[0] = _mm_shufflehi_epi16(y_128[0],0x1e); - ((int16_t*)&y_128[0])[1] = -((int16_t*)&y_128[0])[1]; - ((int16_t*)&y_128[0])[5] = -((int16_t*)&y_128[0])[5]; - y_128[1] = _mm_shufflelo_epi16(y_128[1],0x1e); - y_128[1] = _mm_shufflehi_epi16(y_128[1],0x1e); - ((int16_t*)&y_128[1])[1] = -((int16_t*)&y_128[1])[1]; - ((int16_t*)&y_128[1])[5] = -((int16_t*)&y_128[1])[5]; - y_128[2] = _mm_shufflelo_epi16(y_128[2],0x1e); - y_128[2] = _mm_shufflehi_epi16(y_128[2],0x1e); - ((int16_t*)&y_128[2])[1] = -((int16_t*)&y_128[2])[1]; - ((int16_t*)&y_128[2])[5] = -((int16_t*)&y_128[2])[5]; - y_128[3] = _mm_shufflelo_epi16(y_128[3],0x1e); - y_128[3] = _mm_shufflehi_epi16(y_128[3],0x1e); - ((int16_t*)&y_128[3])[1] = -((int16_t*)&y_128[3])[1]; - ((int16_t*)&y_128[3])[5] = -((int16_t*)&y_128[3])[5]; - } - - - x_128+=4; - y_128 +=4; - } - - - _mm_empty(); - _m_empty(); - - return(0); -} - -int rotate_cpx_vector2(int16_t *x, - int16_t *alpha, - int16_t *y, - uint32_t N, - uint16_t output_shift, - uint8_t format) -{ - // Multiply elementwise two complex vectors of N elements - // x - input 1 in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)| - // We assume x1 with a dynamic of 15 bit maximum - // - // alpha - input 2 in the format |Re0 Im0| - // We assume x2 with a dynamic of 15 bit maximum - // - // y - output in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)| - // - // N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4; - // - // log2_amp - increase the output amplitude by a factor 2^log2_amp (default is 0) - // WARNING: log2_amp>0 can cause overflow!! - - uint32_t i; // loop counter - - register __m128i m0,m1; - - - __m128i *x_128; - __m128i *y_128; - - - shift = _mm_cvtsi32_si128(output_shift); - x_128 = (__m128i *)&x[0]; - - if (format==0) { // alpha is in shuffled format for complex multiply - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = -alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[1]; - ((int16_t *)&alpha_128)[3] = alpha[0]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = -alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[1]; - ((int16_t *)&alpha_128)[7] = alpha[0]; - } else { // input is in shuffled format for complex multiply - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[0]; - ((int16_t *)&alpha_128)[3] = alpha[1]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[0]; - ((int16_t *)&alpha_128)[7] = alpha[1]; - } - - y_128 = (__m128i *)&y[0]; - - // we compute 4 cpx multiply for each loop - for(i=0; i<(N>>1); i++) { - - - m0 = _mm_madd_epi16(x_128[i],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0] - m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude - m1=m0; - m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im] - y_128[i] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im] - if (format==1) { // Put output in proper format (Re,-Im,Im,Re), shuffle = (0,1,3,2) = 0x1e - - y_128[i] = _mm_shufflelo_epi16(y_128[i],0x1e); - y_128[i] = _mm_shufflehi_epi16(y_128[i],0x1e); - ((int16_t*)&y_128[i])[1] = -((int16_t*)&y_128[i])[1]; - ((int16_t*)&y_128[i])[5] = -((int16_t*)&y_128[i])[5]; - } - } - - - _mm_empty(); - _m_empty(); - - - return(0); -} -*/ - -int rotate_cpx_vector(int16_t *x, - int16_t *alpha, - int16_t *y, +#ifdef __AVX2__ +void rotate_cpx_vector(c16_t *x, + c16_t *alpha, + c16_t *y, uint32_t N, uint16_t output_shift) { @@ -372,28 +175,28 @@ int rotate_cpx_vector(int16_t *x, __m128i shift = _mm_cvtsi32_si128(output_shift); register simd_q15_t m0,m1,m2,m3; - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = -alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[1]; - ((int16_t *)&alpha_128)[3] = alpha[0]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = -alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[1]; - ((int16_t *)&alpha_128)[7] = alpha[0]; + ((int16_t *)&alpha_128)[0] = alpha->r; + ((int16_t *)&alpha_128)[1] = -alpha->i; + ((int16_t *)&alpha_128)[2] = alpha->i; + ((int16_t *)&alpha_128)[3] = alpha->r; + ((int16_t *)&alpha_128)[4] = alpha->r; + ((int16_t *)&alpha_128)[5] = -alpha->i; + ((int16_t *)&alpha_128)[6] = alpha->i; + ((int16_t *)&alpha_128)[7] = alpha->r; #elif defined(__arm__) int32x4_t shift; int32x4_t ab_re0,ab_re1,ab_im0,ab_im1,re32,im32; int16_t reflip[8] __attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; int32x4x2_t xtmp; - ((int16_t *)&alpha_128)[0] = alpha[0]; - ((int16_t *)&alpha_128)[1] = alpha[1]; - ((int16_t *)&alpha_128)[2] = alpha[0]; - ((int16_t *)&alpha_128)[3] = alpha[1]; - ((int16_t *)&alpha_128)[4] = alpha[0]; - ((int16_t *)&alpha_128)[5] = alpha[1]; - ((int16_t *)&alpha_128)[6] = alpha[0]; - ((int16_t *)&alpha_128)[7] = alpha[1]; + ((int16_t *)&alpha_128)[0] = alpha->r; + ((int16_t *)&alpha_128)[1] = alpha->i; + ((int16_t *)&alpha_128)[2] = alpha->r; + ((int16_t *)&alpha_128)[3] = alpha->i; + ((int16_t *)&alpha_128)[4] = alpha->r; + ((int16_t *)&alpha_128)[5] = alpha->i; + ((int16_t *)&alpha_128)[6] = alpha->r; + ((int16_t *)&alpha_128)[7] = alpha->i; int16x8_t bflip = vrev32q_s16(alpha_128); int16x8_t bconj = vmulq_s16(alpha_128,*(int16x8_t *)reflip); shift = vdupq_n_s32(-output_shift); @@ -439,9 +242,9 @@ int rotate_cpx_vector(int16_t *x, _mm_empty(); _m_empty(); - return(0); + return; } - +#endif /* int mult_vector32_scalar(int16_t *x1, int x2, @@ -536,7 +339,7 @@ main () int16_t input[256] __attribute__((aligned(16))); int16_t input2[256] __attribute__((aligned(16))); int16_t output[256] __attribute__((aligned(16))); - int16_t alpha[2]; + c16_t alpha; int i; @@ -574,8 +377,8 @@ main () input2[14] = 1000; input2[15] = 2000; - alpha[0]=32767; - alpha[1]=0; + alpha->r=32767; + alpha->i=0; //mult_cpx_vector(input,input2,output,L,0); rotate_cpx_vector_norep(input,alpha,input,L,15); diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index 723813fbb62632ba31b8f82e609a5dc74685174a..d4b28361d2420afc856a36e312ce8dd62bfac026 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -60,7 +60,7 @@ typedef struct OAIgraph { int h; int waterFallh; double *waterFallAvg; - boolean_t initDone; + bool initDone; int iteration; void (*gNBfunct) (struct OAIgraph *graph, scopeData_t *p, int UE_id); void (*nrUEfunct)(scopeGraphData_t **data, struct OAIgraph *graph, PHY_VARS_NR_UE *phy_vars_ue, int eNB_id, int UE_id); @@ -208,7 +208,7 @@ static void oai_xygraph_getbuff(OAIgraph_t *graph, float **x, float **y, int len *y=old_y; } -static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, boolean_t NoAutoScale) { +static void oai_xygraph(OAIgraph_t *graph, float *x, float *y, int len, int layer, bool NoAutoScale) { fl_redraw_object(graph->graph); if ( NoAutoScale && graph->iteration%NoAutoScale == 0) { diff --git a/openair1/PHY/TOOLS/tools_defs.h b/openair1/PHY/TOOLS/tools_defs.h index 839beb3dc9a4f5911ed775dff3e37eaadc59f3ee..c471978f461bb9387cac167b5e5ff8f308d8c5b1 100644 --- a/openair1/PHY/TOOLS/tools_defs.h +++ b/openair1/PHY/TOOLS/tools_defs.h @@ -37,6 +37,7 @@ extern "C" { #include <stdint.h> #include <assert.h> #include "PHY/sse_intrin.h" +#include "common/utils/assertions.h" #define CEILIDIV(a,b) ((a+b-1)/b) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) @@ -104,15 +105,6 @@ void multadd_complex_vector_real_scalar(int16_t *x, uint8_t zero_flag, uint32_t N); -int rotate_cpx_vector(int16_t *x, - int16_t *alpha, - int16_t *y, - uint32_t N, - uint16_t output_shift); - - - - /*!\fn void init_fft(uint16_t size,uint8_t logsize,uint16_t *rev) \brief Initialize the FFT engine for a given size @param size Size of the FFT @@ -461,7 +453,7 @@ idft_size_idx_t get_idft(int ofdm_symbol_size) } -/*!\fn int32_t rotate_cpx_vector(int16_t *x,int16_t *alpha,int16_t *y,uint32_t N,uint16_t output_shift) +/*!\fn int32_t rotate_cpx_vector(c16_t *x,c16_t *alpha,c16_t *y,uint32_t N,uint16_t output_shift) This function performs componentwise multiplication of a vector with a complex scalar. @param x Vector input (Q1.15) in the format |Re0 Im0|,......,|Re(N-1) Im(N-1)| @param alpha Scalar input (Q1.15) in the format |Re0 Im0| @@ -471,11 +463,11 @@ This function performs componentwise multiplication of a vector with a complex s The function implemented is : \f$\mathbf{y} = \alpha\mathbf{x}\f$ */ -int32_t rotate_cpx_vector(int16_t *x, - int16_t *alpha, - int16_t *y, - uint32_t N, - uint16_t output_shift); +void rotate_cpx_vector(c16_t *x, + c16_t *alpha, + c16_t *y, + uint32_t N, + uint16_t output_shift); //cadd_sv.c diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index d13fe260deba559e3b0dcbf3077192289cfa16a5..c93e3a7de9c0fa32b5e81b6305d3a9184d4ff107 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -754,7 +754,7 @@ typedef struct { /// Position of first CCE of the dci int firstCCE; /// flag to indicate that this is a RA response - boolean_t ra_flag; + bool ra_flag; /// rnti rnti_t rnti; /// harq_pid @@ -775,7 +775,7 @@ typedef struct { /// Position of first CCE of the dci int firstCCE; /// flag to indicate that this is a RA response - boolean_t ra_flag; + bool ra_flag; /// rnti rnti_t rnti; /// Format @@ -806,7 +806,7 @@ typedef struct { /// Position of first CCE of the dci int firstCCE; /// flag to indicate that this is a RA response - boolean_t ra_flag; + bool ra_flag; /// rnti rnti_t rnti; /// Format @@ -907,7 +907,7 @@ typedef enum {no_relay=1,unicast_relay_type1,unicast_relay_type2, multicast_rela -#define MCS_COUNT 28 +#define MCS_COUNT 29 #define MCS_TABLE_LENGTH_MAX 64 diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 51601d5f058cc7b3399747385306de6ce0635c81..b8a1e09e1df6072bf4e7cff883c760bcd7dd0bdd 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -188,8 +188,6 @@ typedef struct { uint8_t codebook_index; /// Maximum number of HARQ processes uint8_t Mdlharq; - /// Maximum number of HARQ rounds - uint8_t Mlimit; /// MIMO transmission mode indicator for this sub-frame uint8_t Kmimo; /// Nsoft parameter related to UE Category @@ -345,8 +343,6 @@ typedef struct { typedef struct { /// Pointers to 16 HARQ processes for the ULSCH NR_UL_gNB_HARQ_t *harq_processes[NR_MAX_ULSCH_HARQ_PROCESSES]; - /// Current HARQ process id - int harq_process_id[NR_MAX_SLOTS_PER_FRAME]; /// HARQ process mask, indicates which processes are currently active uint16_t harq_mask; /// ACK/NAK Bundling flag @@ -373,8 +369,6 @@ typedef struct { uint8_t cyclicShift; /// for cooperative communication uint8_t cooperation_flag; - /// Maximum number of HARQ rounds - uint8_t Mlimit; /// Maximum number of LDPC iterations uint8_t max_ldpc_iterations; /// number of iterations used in last LDPC decoding @@ -765,8 +759,8 @@ typedef struct PHY_VARS_gNB_s { /// SRS variables nr_srs_info_t *nr_srs_info[NUMBER_OF_NR_SRS_MAX]; - /// CSI-RS variables - nr_csi_rs_info_t *nr_csi_rs_info; + /// CSI variables + nr_csi_info_t *nr_csi_info; uint8_t pbch_configured; char gNB_generate_rar; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index bd6808c54d2f22f6c3d9163ef594e41ca5b8d152..9896af13fc22bfb91a1c65377e66054f33ae9e09 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -878,8 +878,8 @@ typedef struct { /// SRS variables nr_srs_info_t *nr_srs_info; - /// CSI-RS variables - nr_csi_rs_info_t *nr_csi_rs_info; + /// CSI variables + nr_csi_info_t *nr_csi_info; //#if defined(UPGRADE_RAT_NR) #if 1 @@ -978,8 +978,8 @@ typedef struct { SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX]; SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX]; #endif - - int dl_stats[5]; + int dl_errors; + int dl_stats[8]; void* scopeData; } PHY_VARS_NR_UE; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 9c8e90a9c7ddcb39a295381151e509ed5323178e..33451944efe38017e069dac1cfb346071f8f35ce 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -43,6 +43,7 @@ #define nr_slot_t lte_subframe_t #define MAX_NUM_SUBCARRIER_SPACING 5 +#define NR_MAX_OFDM_SYMBOL_SIZE 4096 #define NR_NB_SC_PER_RB 12 #define NR_NB_REG_PER_CCE 6 @@ -241,35 +242,19 @@ typedef struct { typedef struct { uint16_t sc_list_length; - uint16_t *sc_list; + uint16_t sc_list[6*273]; uint8_t srs_generated_signal_bits; - int32_t *srs_generated_signal; - int32_t **srs_received_signal; - int32_t **srs_ls_estimated_channel; - int32_t **srs_estimated_channel_freq; - int32_t **srs_estimated_channel_time; - int32_t **srs_estimated_channel_time_shifted; - uint32_t *noise_power; + int32_t srs_generated_signal[OFDM_SYMBOL_SIZE_SAMPLES_MAX * MAX_NUM_NR_SRS_SYMBOLS]; } nr_srs_info_t; typedef struct { - uint8_t N_cdm_groups; - uint8_t CDM_group_size; - uint8_t kprime; - uint8_t lprime; - uint8_t N_ports; - uint8_t j[16]; - uint8_t koverline[16]; - uint8_t loverline[16]; uint16_t csi_gold_init; uint32_t ***nr_gold_csi_rs; uint8_t csi_rs_generated_signal_bits; int32_t **csi_rs_generated_signal; - int32_t **csi_rs_received_signal; - int32_t ***csi_rs_ls_estimated_channel; - int32_t ***csi_rs_estimated_channel_freq; - uint32_t *noise_power; -} nr_csi_rs_info_t; + bool csi_im_meas_computed; + uint32_t interference_plus_noise_power; +} nr_csi_info_t; typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; @@ -359,10 +344,10 @@ struct NR_DL_FRAME_PARMS { lte_prefix_type_t Ncp; /// sequence which is computed based on carrier frequency and numerology to rotate/derotate each OFDM symbol according to Section 5.3 in 38.211 /// First dimension is for the direction of the link (0 DL, 1 UL) - int16_t symbol_rotation[2][224*2]; + c16_t symbol_rotation[2][224]; /// sequence used to compensate the phase rotation due to timeshifted OFDM symbols /// First dimenstion is for different CP lengths - int16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16))); + c16_t timeshift_symbol_rotation[4096*2] __attribute__ ((aligned (16))); /// shift of pilot position in one RB uint8_t nushift; /// SRS configuration from TS 38.331 RRC diff --git a/openair1/SCHED/ru_procedures.c b/openair1/SCHED/ru_procedures.c index dc84279a961b5d3b024d96244923e8d758cb10af..443b1c79897ee07cfebb1072a95c1e89d2cf68c9 100644 --- a/openair1/SCHED/ru_procedures.c +++ b/openair1/SCHED/ru_procedures.c @@ -71,9 +71,9 @@ #include "common/utils/system.h" #include <time.h> - -extern int oai_exit; - +#include "openair1/SCHED/sched_common_extern.h" +#include "targets/RT/USER/lte-softmodem.h" +#include "common/ran_context.h" void feptx0(RU_t *ru, int slot) @@ -616,9 +616,11 @@ void init_fep_thread(RU_t *ru, } -extern void kill_fep_thread(RU_t *ru) +void kill_fep_thread(RU_t *ru) { RU_proc_t *proc = &ru->proc; + if (proc->pthread_fep == 0) + return; pthread_mutex_lock( &proc->mutex_fep ); proc->instance_cnt_fep = 0; pthread_cond_signal(&proc->cond_fep); @@ -630,9 +632,11 @@ extern void kill_fep_thread(RU_t *ru) } -extern void kill_feptx_thread(RU_t *ru) +void kill_feptx_thread(RU_t *ru) { RU_proc_t *proc = &ru->proc; + if (proc->pthread_feptx == 0) + return; pthread_mutex_lock( &proc->mutex_feptx ); proc->instance_cnt_feptx = 0; pthread_cond_signal(&proc->cond_feptx); diff --git a/openair1/SCHED/sched_common_extern.h b/openair1/SCHED/sched_common_extern.h index b5edc6f38e390dc027a1f3699c2a05c157778092..2236c5f31dc6d8002c3db22baa3c8e39db1f1403 100644 --- a/openair1/SCHED/sched_common_extern.h +++ b/openair1/SCHED/sched_common_extern.h @@ -29,4 +29,6 @@ extern int16_t hundred_times_delta_TF[100]; extern uint16_t hundred_times_log10_NPRB[100]; +void kill_fep_thread(RU_t *ru); + #endif /*__SCHED_EXTERN_H__ */ diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 48728ba44addaee8fa48cc8330c681862289bb99..5c08a0f479f820785ef5cf83d29481e0cfcf1619 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -251,7 +251,6 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ if (number_dl_pdu>0) oai_nfapi_dl_tti_req(DL_req); - } stop_meas(&gNB->schedule_response_stats); } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 84ba6b6bcd5bae3c759c7e297137143db80241cb..e079caa9e57bddea007e046c66d0fa98ac6bd0bd 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -45,24 +45,12 @@ #include "intertask_interface.h" //#define DEBUG_RXDATA +//#define SRS_IND_DEBUG uint8_t SSB_Table[38]={0,2,4,6,8,10,12,14,254,254,16,18,20,22,24,26,28,30,254,254,32,34,36,38,40,42,44,46,254,254,48,50,52,54,56,58,60,62}; extern uint8_t nfapi_mode; -void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME_PARMS *fp) { - - uint8_t sco = 0; - if (((fp->freq_range == nr_FR1) && (cfg->ssb_table.ssb_subcarrier_offset.value<24)) || - ((fp->freq_range == nr_FR2) && (cfg->ssb_table.ssb_subcarrier_offset.value<12)) ) { - if (fp->freq_range == nr_FR1) - sco = cfg->ssb_table.ssb_subcarrier_offset.value>>cfg->ssb_config.scs_common.value; - } - - fp->ssb_start_subcarrier = (12 * cfg->ssb_table.ssb_offset_point_a.value + sco); - LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco); -} - void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu) { NR_DL_FRAME_PARMS *fp=&gNB->frame_parms; @@ -84,7 +72,12 @@ void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_ int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp,ssb_index); // computing the starting symbol for current ssb ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot - nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier + // setting the first subcarrier + const int scs = cfg->ssb_config.scs_common.value; + const int prb_offset = (fp->freq_range == nr_FR1) ? ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA>>scs : ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA>>(scs-2); + const int sc_offset = (fp->freq_range == nr_FR1) ? ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset>>scs : ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset; + fp->ssb_start_subcarrier = (12 * prb_offset + sc_offset); + LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier, prb_offset, sc_offset); LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol); nr_generate_pss(&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp); @@ -179,7 +172,7 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx, if (csirs->active == 1) { LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot); nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15; - nr_generate_csi_rs(gNB->frame_parms, gNB->common_vars.txdataF, AMP, gNB->nr_csi_rs_info, csi_params, slot); + nr_generate_csi_rs(&gNB->frame_parms, gNB->common_vars.txdataF, AMP, gNB->nr_csi_info, csi_params, slot, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); csirs->active = 0; } } @@ -200,14 +193,12 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { NR_gNB_ULSCH_t *ulsch = rdata->ulsch; int r = rdata->segment_r; nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[rdata->ulsch_id]->harq_processes[rdata->harq_pid]->ulsch_pdu; - bool decodeSuccess = (rdata->decodeIterations <= rdata->decoderParms.numMaxIter); ulsch_harq->processedSegments++; LOG_D(PHY, "processing result of segment: %d, processed %d/%d\n", rdata->segment_r, ulsch_harq->processedSegments, rdata->nbSegments); gNB->nbDecode--; LOG_D(PHY,"remain to decoded in subframe: %d\n", gNB->nbDecode); - if (decodeSuccess) { memcpy(ulsch_harq->b+rdata->offset, ulsch_harq->c[r], @@ -229,7 +220,7 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { //int dumpsig=0; // if all segments are done if (rdata->nbSegments == ulsch_harq->processedSegments) { - if (decodeSuccess) { + if (decodeSuccess && !gNB->pusch_vars[rdata->ulsch_id]->DTX) { LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for SFN/SF %d.%d (pid %d, ndi %d, status %d, round %d, TBS %d, Max interation (all seg) %d)\n", gNB->Mod_id,ulsch_harq->frame,ulsch_harq->slot,rdata->harq_pid,pusch_pdu->pusch_data.new_data_indicator,ulsch_harq->status,ulsch_harq->round,ulsch_harq->TBS,rdata->decodeIterations); ulsch_harq->status = SCH_IDLE; @@ -249,13 +240,6 @@ void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) { ulsch_harq->ulsch_pdu.rb_size, ulsch_harq->TBS, r); - ulsch_harq->round++; - if (ulsch_harq->round >= ulsch->Mlimit) { - ulsch_harq->status = SCH_IDLE; - ulsch_harq->round = 0; - ulsch_harq->handled = 0; - ulsch->harq_mask &= ~(1 << rdata->harq_pid); - } ulsch_harq->handled = 1; LOG_D(PHY, "ULSCH %d in error\n",rdata->ulsch_id); @@ -421,17 +405,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, if (timing_advance_update > 63) timing_advance_update = 63; if (crc_flag == 0) LOG_D(PHY, "%d.%d : Received PUSCH : Estimated timing advance PUSCH is = %d, timing_advance_update is %d \n", frame,slot_rx,sync_pos,timing_advance_update); - else if (harq_process->round>0 || dtx_flag == 0) { // increment round if crc_flag == 1 and not(dtx_flag ==1 and round==0) - harq_process->round++; - if (harq_process->round >= ulsch->Mlimit) { - harq_process->status = SCH_IDLE; - harq_process->round = 0; - harq_process->handled = 0; - ulsch->harq_mask &= ~(1 << harq_pid); - } - } - // estimate UL_CQI for MAC + // estimate UL_CQI for MAC int SNRtimes10 = dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_power_tot) - dB_fixed_x10(gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot); @@ -582,7 +557,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { LOG_D(PHY,"symbol %d Filling rb_mask_ul rb_size %d\n",symbol,ulsch_harq->ulsch_pdu.rb_size); for (rb=0; rb<ulsch_harq->ulsch_pdu.rb_size; rb++) { rb2 = rb+ulsch_harq->ulsch_pdu.rb_start+ulsch_harq->ulsch_pdu.bwp_start; - gNB->rb_mask_ul[symbol][rb2>>5] |= (1<<(rb2&31)); + gNB->rb_mask_ul[symbol][rb2 >> 5] |= 1U << (rb2 & 31); } } } @@ -634,10 +609,38 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) } +int fill_srs_reported_symbol_list(nfapi_nr_srs_indication_reported_symbol_t *reported_symbol_list, + const nfapi_nr_srs_pdu_t *srs_pdu, + const int N_RB_UL, + const int8_t *snr_per_rb, + const int srs_est) { + + reported_symbol_list->num_rbs = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0]; + + if (!reported_symbol_list->rb_list) { + reported_symbol_list->rb_list = (nfapi_nr_srs_indication_reported_symbol_resource_block_t*) calloc(1, N_RB_UL*sizeof(nfapi_nr_srs_indication_reported_symbol_resource_block_t)); + } + + for(int rb = 0; rb < reported_symbol_list->num_rbs; rb++) { + if (srs_est<0) { + reported_symbol_list->rb_list[rb].rb_snr = 0xFF; + } else if (snr_per_rb[rb] < -64) { + reported_symbol_list->rb_list[rb].rb_snr = 0; + } else if (snr_per_rb[rb] > 63) { + reported_symbol_list->rb_list[rb].rb_snr = 0xFE; + } else { + reported_symbol_list->rb_list[rb].rb_snr = (snr_per_rb[rb] + 64)<<1; + } + } + + return 0; +} + int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { /* those variables to log T_GNB_PHY_PUCCH_PUSCH_IQ only when we try to decode */ int pucch_decode_done = 0; int pusch_decode_done = 0; + int pusch_DTX = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,1); LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx); @@ -708,6 +711,7 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { LOG_D(PHY,"%d.%d Calling nr_decode_pucch2\n",frame_rx,slot_rx); nr_decode_pucch2(gNB, + frame_rx, slot_rx, uci_pdu_format2, pucch_pdu); @@ -724,14 +728,12 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { for (int ULSCH_id=0;ULSCH_id<gNB->number_of_nr_ulsch_max;ULSCH_id++) { NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ULSCH_id]; - int harq_pid; - int no_sig; NR_UL_gNB_HARQ_t *ulsch_harq; if ((ulsch) && (ulsch->rnti > 0)) { // for for an active HARQ process - for (harq_pid=0;harq_pid<NR_MAX_ULSCH_HARQ_PROCESSES;harq_pid++) { + for (int harq_pid=0;harq_pid<NR_MAX_ULSCH_HARQ_PROCESSES;harq_pid++) { ulsch_harq = ulsch->harq_processes[harq_pid]; AssertFatal(ulsch_harq!=NULL,"harq_pid %d is not allocated\n",harq_pid); if ((ulsch_harq->status == NR_ACTIVE) && @@ -772,16 +774,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { pusch_decode_done = 1; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,1); - start_meas(&gNB->rx_pusch_stats); - no_sig = nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, harq_pid); - stop_meas(&gNB->rx_pusch_stats); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_NR_RX_PUSCH,0); - - if (no_sig) { - LOG_D(PHY, "PUSCH not detected in frame %d, slot %d\n", frame_rx, slot_rx); - nr_fill_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1); - return 1; - } + start_meas(&gNB->rx_pusch_stats); + nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, harq_pid); gNB->pusch_vars[ULSCH_id]->ulsch_power_tot=0; gNB->pusch_vars[ULSCH_id]->ulsch_noise_power_tot=0; for (int aarx=0;aarx<gNB->frame_parms.nb_antennas_rx;aarx++) { @@ -804,7 +798,8 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { /* in case of phy_test mode, we still want to decode to measure execution time. Therefore, we don't yet call nr_fill_indication, it will be called later */ nr_fill_indication(gNB,frame_rx, slot_rx, ULSCH_id, harq_pid, 1,1); - return 1; + pusch_DTX++; + continue; } } else { LOG_D(PHY, "PUSCH detected in %d.%d (%d,%d,%d)\n",frame_rx,slot_rx, @@ -833,29 +828,88 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { LOG_D(NR_PHY, "(%d.%d) gNB is waiting for SRS, id = %i\n", frame_rx, slot_rx, i); + NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; nfapi_nr_srs_pdu_t *srs_pdu = &srs->srs_pdu; + uint8_t N_symb_SRS = 1<<srs_pdu->num_symbols; + int32_t srs_received_signal[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS]; + int32_t srs_ls_estimated_channel[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS]; + int32_t srs_estimated_channel_freq[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size*N_symb_SRS] __attribute__ ((aligned(32))); + int32_t srs_estimated_channel_time[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size] __attribute__ ((aligned(32))); + int32_t srs_estimated_channel_time_shifted[frame_parms->nb_antennas_rx][frame_parms->ofdm_symbol_size]; + uint32_t noise_power_per_rb[srs_pdu->bwp_size]; + int8_t snr_per_rb[srs_pdu->bwp_size]; + uint32_t signal_power; + uint32_t noise_power; + int8_t snr; // At least currently, the configuration is constant, so it is enough to generate the sequence just once. if(gNB->nr_srs_info[i]->sc_list_length == 0) { - generate_srs_nr(srs_pdu, &gNB->frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx); + generate_srs_nr(srs_pdu, frame_parms, gNB->nr_srs_info[i]->srs_generated_signal, gNB->nr_srs_info[i], AMP, frame_rx, slot_rx); } - nr_get_srs_signal(gNB,frame_rx,slot_rx,srs_pdu, gNB->nr_srs_info[i], gNB->nr_srs_info[i]->srs_received_signal); - - nr_srs_channel_estimation(gNB,frame_rx,slot_rx,srs_pdu, - gNB->nr_srs_info[i], - gNB->nr_srs_info[i]->srs_generated_signal, - gNB->nr_srs_info[i]->srs_received_signal, - gNB->nr_srs_info[i]->srs_estimated_channel_freq, - gNB->nr_srs_info[i]->srs_estimated_channel_time, - gNB->nr_srs_info[i]->srs_estimated_channel_time_shifted, - gNB->nr_srs_info[i]->noise_power); + const int srs_est = nr_get_srs_signal(gNB,frame_rx,slot_rx, srs_pdu, gNB->nr_srs_info[i], srs_received_signal); + + if (srs_est >= 0) { + nr_srs_channel_estimation(gNB, + frame_rx, + slot_rx, + srs_pdu, + gNB->nr_srs_info[i], + gNB->nr_srs_info[i]->srs_generated_signal, + srs_received_signal, + srs_ls_estimated_channel, + srs_estimated_channel_freq, + srs_estimated_channel_time, + srs_estimated_channel_time_shifted, + &signal_power, + noise_power_per_rb, + &noise_power, + snr_per_rb, + &snr); + } T(T_GNB_PHY_UL_FREQ_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0), - T_BUFFER(gNB->nr_srs_info[i]->srs_estimated_channel_freq[0], gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t))); + T_BUFFER(srs_estimated_channel_freq[0], frame_parms->ofdm_symbol_size*sizeof(int32_t))); T(T_GNB_PHY_UL_TIME_CHANNEL_ESTIMATE, T_INT(0), T_INT(srs_pdu->rnti), T_INT(frame_rx), T_INT(0), T_INT(0), - T_BUFFER(gNB->nr_srs_info[i]->srs_estimated_channel_time_shifted[0], gNB->frame_parms.ofdm_symbol_size*sizeof(int32_t))); + T_BUFFER(srs_estimated_channel_time_shifted[0], frame_parms->ofdm_symbol_size*sizeof(int32_t))); + + const uint16_t num_srs = gNB->UL_INFO.srs_ind.number_of_pdus; + gNB->UL_INFO.srs_ind.pdu_list = &gNB->srs_pdu_list[0]; + gNB->UL_INFO.srs_ind.sfn = frame_rx; + gNB->UL_INFO.srs_ind.slot = slot_rx; + gNB->srs_pdu_list[num_srs].handle = srs_pdu->handle; + gNB->srs_pdu_list[num_srs].rnti = srs_pdu->rnti; + gNB->srs_pdu_list[num_srs].timing_advance = srs_est >= 0 ? nr_est_timing_advance_srs(frame_parms, + srs_estimated_channel_time) : 0xFFFF; + gNB->srs_pdu_list[num_srs].num_symbols = 1<<srs_pdu->num_symbols; + gNB->srs_pdu_list[num_srs].wide_band_snr = srs_est >= 0 ? (snr + 64)<<1 : 0xFF; // 0xFF will be set if this field is invalid + gNB->srs_pdu_list[num_srs].num_reported_symbols = 1<<srs_pdu->num_symbols; + if(!gNB->srs_pdu_list[num_srs].reported_symbol_list) { + gNB->srs_pdu_list[num_srs].reported_symbol_list = (nfapi_nr_srs_indication_reported_symbol_t*) calloc(1, gNB->srs_pdu_list[num_srs].num_reported_symbols*sizeof(nfapi_nr_srs_indication_reported_symbol_t)); + } + fill_srs_reported_symbol_list(&gNB->srs_pdu_list[num_srs].reported_symbol_list[0], + srs_pdu, + frame_parms->N_RB_UL, + snr_per_rb, + srs_est); + + gNB->UL_INFO.srs_ind.number_of_pdus += 1; + +#ifdef SRS_IND_DEBUG + LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.sfn = %i\n", gNB->UL_INFO.srs_ind.sfn); + LOG_I(NR_PHY, "gNB->UL_INFO.srs_ind.slot = %i\n", gNB->UL_INFO.srs_ind.slot); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].rnti = 0x%04x\n", num_srs, gNB->srs_pdu_list[num_srs].rnti); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].timing_advance = %i\n", num_srs, gNB->srs_pdu_list[num_srs].timing_advance); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].num_symbols = %i\n", num_srs, gNB->srs_pdu_list[num_srs].num_symbols); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].wide_band_snr = %i\n", num_srs, gNB->srs_pdu_list[num_srs].wide_band_snr); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].num_reported_symbols = %i\n", num_srs, gNB->srs_pdu_list[num_srs].num_reported_symbols); + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].reported_symbol_list[0].num_rbs = %i\n", num_srs, gNB->srs_pdu_list[num_srs].reported_symbol_list[0].num_rbs); + for(int rb = 0; rb < gNB->srs_pdu_list[num_srs].reported_symbol_list[0].num_rbs; rb++) { + LOG_I(NR_PHY, "gNB->srs_pdu_list[%i].reported_symbol_list[0].rb_list[%3i].rb_snr = %i\n", + num_srs, rb, gNB->srs_pdu_list[num_srs].reported_symbol_list[0].rb_list[rb].rb_snr); + } +#endif srs->active = 0; } @@ -869,5 +923,5 @@ int phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_UESPEC_RX,0); - return 0; + return pusch_DTX; } diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index 7672aee8a25a7121e0061b5060f41cb16817d1ef..fa354d228432f85487f1e3f76c2597b250671c7f 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -405,7 +405,7 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, NR_UE_DLSCH_t *dlsch1, uint16_t n_pdus, UE_nr_rxtx_proc_t *proc, - void * typeSpecific); + void *typeSpecific); bool nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index 046f67a7d000c15f034ea1d90f8de53f1f340610..f4c863bb408c417ae5728986f229a3880fc5b9f9 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -393,7 +393,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ case FAPI_NR_DL_CONFIG_TYPE_CSI_IM: csiim_config_pdu = &dl_config->dl_config_list[i].csiim_config_pdu.csiim_config_rel15; memcpy((void*)&(csiim_vars->csiim_config_pdu), (void*)csiim_config_pdu, sizeof(fapi_nr_dl_config_csiim_pdu_rel15_t)); - csirs_vars->active = true; + csiim_vars->active = true; break; case FAPI_NR_DL_CONFIG_TYPE_CSI_RS: csirs_config_pdu = &dl_config->dl_config_list[i].csirs_config_pdu.csirs_config_rel15; diff --git a/openair1/SCHED_NR_UE/harq_nr.c b/openair1/SCHED_NR_UE/harq_nr.c index a9ff01d78a471cb5dc51016a3cbfd04f476c575e..dc62ea646c86ca36e2118631b0d28a8a8af26cdd 100644 --- a/openair1/SCHED_NR_UE/harq_nr.c +++ b/openair1/SCHED_NR_UE/harq_nr.c @@ -308,7 +308,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) dl_harq->status = SCH_IDLE; dl_harq->first_rx = 1; dl_harq->DLround = 0; - dl_harq->DCINdi = 1; + dl_harq->Ndi = 2; // set to an invalid value dl_harq->ack = DL_ACKNACK_NO_SET; } @@ -329,7 +329,7 @@ void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) * *********************************************************************/ -void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int rv, uint8_t rnti_type) { +void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int dci_ndi, int rv, uint8_t rnti_type) { if (rnti_type == _SI_RNTI_ || rnti_type == _P_RNTI_ || @@ -339,10 +339,9 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int dl_harq->first_rx = 1; } else { LOG_D(PHY,"receive harq process: %p harqPid=%d, rv=%d, ndi=%d, rntiType=%d new transmission= %s\n", - dl_harq, harq_pid, rv, ndi, rnti_type, dl_harq->DCINdi != ndi ? "yes":"no"); + dl_harq, harq_pid, rv, dci_ndi, rnti_type, dl_harq->Ndi != dci_ndi ? "yes":"no"); AssertFatal(rv<4 && rv>=0, "invalid redondancy version %d\n", rv); - - if (ndi!=dl_harq->DCINdi) { + if (dci_ndi!=dl_harq->Ndi) { if (dl_harq->ack == DL_NACK) LOG_D(PHY,"New transmission on a harq pid (%d) never acknowledged\n", harq_pid); else @@ -354,7 +353,7 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int LOG_D(PHY,"Starting retransmission on a harq pid (%d), rv (%d)\n", harq_pid, rv); } - if (ndi!=dl_harq->DCINdi) { + if (dci_ndi!=dl_harq->Ndi) { dl_harq->first_rx = true; dl_harq->DLround = 0; } else { @@ -364,7 +363,7 @@ void downlink_harq_process(NR_DL_UE_HARQ_t *dl_harq, int harq_pid, int ndi, int dl_harq->status = ACTIVE; - dl_harq->DCINdi = ndi; + dl_harq->Ndi = dci_ndi; //dl_harq->status = SCH_IDLE; } } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index d366ae9ec17591bfe70c73c47a28fdc409054776..09c24d676dc3b834854f01d62c4567adf3f9e916 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -121,9 +121,8 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, NR_UE_DLSCH_t *dlsch0, NR_UE_DLSCH_t *dlsch1, uint16_t n_pdus, - UE_nr_rxtx_proc_t *proc, - void * typeSpecific){ - + UE_nr_rxtx_proc_t *proc, + void *typeSpecific){ NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; @@ -176,6 +175,11 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.ssb_start_subcarrier = frame_parms->ssb_start_subcarrier; rx_ind->rx_indication_body[n_pdus - 1].ssb_pdu.rsrp_dBm = ue->measurements.rsrp_dBm[gNB_id]; break; + case FAPI_NR_CSIRS_IND: + memcpy(&rx_ind->rx_indication_body[n_pdus - 1].csirs_measurements, + (fapi_nr_csirs_measurements_t*)typeSpecific, + sizeof(*(fapi_nr_csirs_measurements_t*)typeSpecific)); + break; default: break; } @@ -1321,8 +1325,7 @@ int is_ssb_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_ //uint8_t half_frame_index = fp->half_frame_bit; //uint8_t i_ssb = fp->ssb_index; uint8_t Lmax = fp->Lmax; - - if (!(frame%(1<<(config->ssb_table.ssb_period-1)))){ + if ((config->ssb_table.ssb_period > 0) && !(frame % (1 << (config->ssb_table.ssb_period - 1)))) { if(Lmax <= 8) { if(slot <=3 && (((config->ssb_table.ssb_mask_list[0].ssb_mask << 2*slot)&0x80000000) == 0x80000000 || ((config->ssb_table.ssb_mask_list[0].ssb_mask << (2*slot +1))&0x80000000) == 0x80000000)) @@ -1477,7 +1480,17 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if ((frame_rx%64 == 0) && (nr_slot_rx==0)) { LOG_I(NR_PHY,"============================================\n"); - LOG_I(NR_PHY,"Harq round stats for Downlink: %d/%d/%d/%d DLSCH errors: %d\n",ue->dl_stats[0],ue->dl_stats[1],ue->dl_stats[2],ue->dl_stats[3],ue->dl_stats[4]); + // fixed text + 8 HARQs rounds à 10 ("999999999/") + NULL + // if we use 999999999 HARQs, that should be sufficient for at least 138 hours + const size_t harq_output_len = 31 + 10 * 8 + 1; + char output[harq_output_len]; + char *p = output; + const char *end = output + harq_output_len; + p += snprintf(p, end - p, "Harq round stats for Downlink: %d", ue->dl_stats[0]); + for (int round = 1; round < 16 && (round < 3 || ue->dl_stats[round] != 0); ++round) + p += snprintf(p, end - p,"/%d", ue->dl_stats[round]); + LOG_I(NR_PHY,"%s/0\n", output); + LOG_I(NR_PHY,"============================================\n"); } @@ -1692,6 +1705,19 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, // do procedures for CSI-IM if ((ue->csiim_vars[gNB_id]) && (ue->csiim_vars[gNB_id]->active == 1)) { + int l_csiim[4] = {-1, -1, -1, -1}; + for(int symb_idx = 0; symb_idx < 4; symb_idx++) { + bool nr_slot_fep_done = false; + for (int symb_idx2 = 0; symb_idx2 < symb_idx; symb_idx2++) { + if (l_csiim[symb_idx2] == ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx]) { + nr_slot_fep_done = true; + } + } + l_csiim[symb_idx] = ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx]; + if(nr_slot_fep_done == false) { + nr_slot_fep(ue, proc, ue->csiim_vars[gNB_id]->csiim_config_pdu.l_csiim[symb_idx], nr_slot_rx); + } + } nr_ue_csi_im_procedures(ue, proc, gNB_id); ue->csiim_vars[gNB_id]->active = 0; } diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index aa0ff0db80fe9506d796f9f927464e11add22a38..cdf4cf39f9a59696050985080b93f40a82769fe7 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -460,7 +460,7 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue, is_pucch2_subframe = (is_ri_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0)) || is_pucch2_subframe; // check ACK/SR transmission - if(frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission == FALSE) { + if(frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission == false) { if(is_SR_TXOp(ue,proc,eNB_id)) { uint32_t SR_payload = 0; diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 231d63cf047254821caa07336cf5c1401c4bf775..8aff47c86b8159ab260d10741042833de90f18db 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -512,12 +512,16 @@ int main(int argc, char **argv) { int re; int s,Kr,Kr_bytes; LTE_DL_FRAME_PARMS *frame_parms; - double s_re0[30720*2],s_im0[30720*2],r_re0[30720*2],r_im0[30720*2]; - double s_re1[30720*2],s_im1[30720*2],r_re1[30720*2],r_im1[30720*2]; - double *s_re[2]= {s_re0,s_re1}; - double *s_im[2]= {s_im0,s_im1}; - double *r_re[2]= {r_re0,r_re1}; - double *r_im[2]= {r_im0,r_im1}; + double *tmpTX[4], *tmpRX[4] ; + for (int i = 0; i < 4; i++) { + tmpTX[i] = malloc(30720 * NB_ANTENNAS_TX * sizeof(*tmpTX)); + tmpRX[i] = malloc(30720 * NB_ANTENNAS_RX * sizeof(*tmpRX)); + } + double *s_re[NB_ANTENNAS_TX] = {tmpTX[0], tmpTX[1]}; + double *s_im[NB_ANTENNAS_TX] = {tmpTX[2], tmpTX[3]}; + double *r_re[NB_ANTENNAS_RX] = {tmpRX[0], tmpRX[1]}; + double *r_im[NB_ANTENNAS_RX] = {tmpRX[2], tmpRX[3]}; + uint8_t transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2; int eNB_id = 0; unsigned char round; diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 0843d00ffd8ea4ce5921560ddcb15019c540fce4..0f98eb337a66d42b18b1971791dce39263e3cf87 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -358,7 +358,7 @@ int main(int argc, char **argv) { unsigned short input_buffer_length; unsigned int ret; unsigned int coded_bits_per_codeword,nsymb; - unsigned int tx_lev=0,tx_lev_dB=0,trials,errs[5]= {0,0,0,0,0},round_trials[4]= {0,0,0,0}; + unsigned int tx_lev = 0, tx_lev_dB = 0, trials, errs[6] = {0}, round_trials[4] = {0}; FILE *bler_fd=NULL; char bler_fname[512]; FILE *time_meas_fd=NULL; @@ -387,7 +387,6 @@ int main(int argc, char **argv) { double cpu_freq_GHz; int iter_trials; uint32_t UL_alloc_pdu; - int s,Kr,Kr_bytes; int dump_perf=0; static int dump_table =0; double effective_rate=0.0; @@ -1233,20 +1232,21 @@ int main(int argc, char **argv) { if (n_frames==1) { printf("ULSCH errors found o_ACK[0]= %d\n",eNB->ulsch[0]->harq_processes[harq_pid]->o_ACK[0]); - +#ifdef DUMP_EACH_VALUE + int Kr_bytes; for (s=0; s<eNB->ulsch[0]->harq_processes[harq_pid]->C; s++) { if (s<eNB->ulsch[0]->harq_processes[harq_pid]->Cminus) - Kr = eNB->ulsch[0]->harq_processes[harq_pid]->Kminus; + Kr_bytes = eNB->ulsch[0]->harq_processes[harq_pid]->Kminus; else - Kr = eNB->ulsch[0]->harq_processes[harq_pid]->Kplus; - - Kr_bytes = Kr>>3; + Kr_bytes = eNB->ulsch[0]->harq_processes[harq_pid]->Kplus; + Kr_bytes = Kr_bytes >> 3; printf("Decoded_output (Segment %d):\n",s); for (i=0; i<Kr_bytes; i++) printf("%d : %x (%x)\n",i,eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i], eNB->ulsch[0]->harq_processes[harq_pid]->c[s][i]^UE->ulsch[0]->harq_processes[harq_pid]->c[s][i]); } +#endif dump_ulsch(eNB,eNB->proc.frame_rx,subframe,0,round); round=5; diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index d3da01638ad7385d17fb16593da0f5610d72014c..5141fc2c79192297e2d6d85b90a67f13def4a44c 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -115,16 +115,16 @@ int main(int argc, char **argv) //int run_initial_sync=0; int loglvl = OAILOG_WARNING; uint8_t dlsch_threads = 0; - float target_error_rate = 0.01; - uint64_t SSB_positions=0x01; - uint16_t nb_symb_sch = 12; - uint16_t nb_rb = 50; - uint8_t Imcs = 9; - uint8_t mcs_table = 0; - double DS_TDL = .03; - cpuf = get_cpu_freq_GHz(); - char gNBthreads[128]="n"; - int Tbslbrm = 950984; + float target_error_rate = 0.01; + uint64_t SSB_positions=0x01; + uint16_t nb_symb_sch = 12; + uint16_t nb_rb = 50; + uint8_t Imcs = 9; + uint8_t mcs_table = 0; + double DS_TDL = .03; + cpuf = get_cpu_freq_GHz(); + char gNBthreads[128]="n"; + int Tbslbrm = 950984; if (load_configmodule(argc, argv, CONFIG_ENABLECMDLINEONLY) == 0) { exit_fun("[NR_DLSCHSIM] Error, configuration module init failed\n"); @@ -300,7 +300,7 @@ int main(int argc, char **argv) break; case 'X': - strncpy(gNBthreads, optarg, sizeof(gNBthreads)); + strncpy(gNBthreads, optarg, sizeof(gNBthreads)-1); gNBthreads[sizeof(gNBthreads)-1]=0; break; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 1a526174f01fbc883b8d55158f4762743685ae75..3ff3fe66cd09524150ce383ee088863b3b509ff6 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -100,9 +100,17 @@ nfapi_ue_release_request_body_t release_rntis; //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; -teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid, - transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) { -return 0; +teid_t newGtpuCreateTunnel(instance_t instance, + rnti_t rnti, + int incoming_bearer_id, + int outgoing_bearer_id, + teid_t outgoing_teid, + int qfi, + transport_layer_addr_t remoteAddr, + int port, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP) { + return 0; } int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) { @@ -210,7 +218,6 @@ int nr_derive_key(int alg_type, uint8_t alg_id, } void config_common(int Mod_idP, - int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc); @@ -242,10 +249,10 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(module_id_t module_idP, return 0; } -nr_bler_struct nr_bler_data[NR_NUM_MCS]; - void processSlotTX(void *arg) {} +nr_bler_struct nr_bler_data[NR_NUM_MCS]; + //nFAPI P7 dummy functions to avoid linking errors int oai_nfapi_dl_tti_req(nfapi_nr_dl_tti_request_t *dl_config_req) { return(0); } @@ -273,10 +280,9 @@ void nr_dlsim_preprocessor(module_id_t module_id, NR_UE_info_t *UE_info = RC.nrmac[module_id]->UE_info.list[0]; AssertFatal(RC.nrmac[module_id]->UE_info.list[1]==NULL, "can have only a single UE\n"); NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl; + NR_UE_DL_BWP_t *current_BWP = &UE_info->current_DL_BWP; NR_ServingCellConfigCommon_t *scc = RC.nrmac[0]->common_channels[0].ServingCellConfigCommon; - const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - sched_ctrl->search_space = get_searchspace(NULL, scc, sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, target_ss); uint8_t nr_of_candidates = 0; if (g_mcsIndex < 4) { find_aggregation_candidates(&sched_ctrl->aggregation_level, @@ -288,7 +294,6 @@ void nr_dlsim_preprocessor(module_id_t module_id, &nr_of_candidates, sched_ctrl->search_space,4); } - sched_ctrl->coreset = get_coreset(RC.nrmac[module_id], scc, sched_ctrl->active_bwp->bwp_Dedicated, sched_ctrl->search_space, target_ss); uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE_info->rnti); int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], /* CC_id = */ 0, @@ -302,11 +307,8 @@ void nr_dlsim_preprocessor(module_id_t module_id, NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; - nr_set_pdsch_semi_static(NULL, + nr_set_pdsch_semi_static(current_BWP, scc, - UE_info->CellGroup, - sched_ctrl->active_bwp, - NULL, /* tda = */ 0, g_nrOfLayers, sched_ctrl, @@ -318,10 +320,10 @@ void nr_dlsim_preprocessor(module_id_t module_id, sched_pdsch->mcs = g_mcsIndex; /* the following might override the table that is mandated by RRC * configuration */ - ps->mcsTableIdx = g_mcsTableIdx; + current_BWP->mcsTableIdx = g_mcsTableIdx; - sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); - sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); + sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); + sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm, sched_pdsch->R, sched_pdsch->rbSize, @@ -349,7 +351,7 @@ void nr_dlsim_preprocessor(module_id_t module_id, AssertFatal(sched_pdsch->rbStart >= 0, "invalid rbStart %d\n", sched_pdsch->rbStart); AssertFatal(sched_pdsch->rbSize > 0, "invalid rbSize %d\n", sched_pdsch->rbSize); AssertFatal(sched_pdsch->mcs >= 0, "invalid mcs %d\n", sched_pdsch->mcs); - AssertFatal(ps->mcsTableIdx >= 0 && ps->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", ps->mcsTableIdx); + AssertFatal(current_BWP->mcsTableIdx >= 0 && current_BWP->mcsTableIdx <= 2, "invalid mcsTableIdx %d\n", current_BWP->mcsTableIdx); } typedef struct { @@ -671,7 +673,7 @@ int main(int argc, char **argv) break; case 'X': - strncpy(gNBthreads, optarg, sizeof(gNBthreads)); + strncpy(gNBthreads, optarg, sizeof(gNBthreads)-1); gNBthreads[sizeof(gNBthreads)-1]=0; break; @@ -757,11 +759,13 @@ int main(int argc, char **argv) RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); for (i = 0; i < RC.nb_nr_macrlc_inst; i++) RC.nb_nr_mac_CC[i] = 1; - mac_top_init_gNB(); + mac_top_init_gNB(ngran_gNB); gNB_mac = RC.nrmac[0]; gNB_RRC_INST rrc; memset((void*)&rrc,0,sizeof(rrc)); + gNB_mac->dl_bler.harq_round_max = num_rounds; + /* // read in SCGroupConfig AssertFatal(scg_fd != NULL,"no reconfig.raw file\n"); @@ -857,9 +861,9 @@ int main(int argc, char **argv) gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration - rrc_mac_config_req_gNB(0,0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, NULL, 0, 0, NULL); + rrc_mac_config_req_gNB(0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, NULL, 0, 0, NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, NULL, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); + rrc_mac_config_req_gNB(0, pdsch_AntennaPorts, n_tx, 0, 6, scc, NULL, NULL, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity,secondaryCellGroup); // reset preprocessor to the one of DLSIM after it has been set during // rrc_mac_config_req_gNB gNB_mac->pre_processor_dl = nr_dlsim_preprocessor; @@ -867,6 +871,8 @@ int main(int argc, char **argv) N_RB_DL = gNB->frame_parms.N_RB_DL; NR_UE_info_t *UE_info = RC.nrmac[0]->UE_info.list[0]; + configure_UE_BWP(RC.nrmac[0], scc, &UE_info->UE_sched_ctrl, NULL, UE_info); + // stub to configure frame_parms // nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); // call MAC to configure common parameters @@ -878,55 +884,22 @@ int main(int argc, char **argv) if (g_rbStart < 0) g_rbStart=0; if (g_rbSize < 0) g_rbSize = N_RB_DL - g_rbStart; - double fs,bw; + double fs,txbw,rxbw; + uint32_t samples; - if (mu == 0 && N_RB_DL == 25) { - fs = 7.68e6; - bw = 5e6; - } - else if (mu == 1 && N_RB_DL == 217) { - fs = 122.88e6; - bw = 80e6; - } - else if (mu == 1 && N_RB_DL == 245) { - fs = 122.88e6; - bw = 90e6; - } - else if (mu == 1 && N_RB_DL == 273) { - fs = 122.88e6; - bw = 100e6; - } - else if (mu == 1 && N_RB_DL == 106) { - fs = 61.44e6; - bw = 40e6; - } - else if (mu == 1 && N_RB_DL == 133) { - fs = 61.44e6; - bw = 50e6; - } - else if (mu == 1 && N_RB_DL == 162) { - fs = 61.44e6; - bw = 60e6; - } - else if (mu == 1 && N_RB_DL == 24) { - fs = 15.36e6; - bw = 10e6; - } - else if (mu == 3 && N_RB_DL == 66) { - fs = 122.88e6; - bw = 100e6; - } - else if (mu == 3 && N_RB_DL == 32) { - fs = 61.44e6; - bw = 50e6; - } - else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); + get_samplerate_and_bw(mu, + N_RB_DL, + frame_parms->threequarter_fs, + &fs, + &samples, + &txbw, + &rxbw); gNB2UE = new_channel_desc_scm(n_tx, n_rx, channel_model, fs/1e6,//sampling frequency in MHz - bw, + txbw, 30e-9, 0, 0, @@ -1143,7 +1116,7 @@ int main(int argc, char **argv) Sched_INFO.frame = frame; Sched_INFO.slot = slot; Sched_INFO.DL_req = &gNB_mac->DL_req[0]; - Sched_INFO.UL_tti_req = gNB_mac->UL_tti_req_ahead[slot]; + Sched_INFO.UL_tti_req = gNB_mac->UL_tti_req_ahead[0]; Sched_INFO.UL_dci_req = NULL; Sched_INFO.TX_req = &gNB_mac->TX_req[0]; pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx); diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index 21802cd41a9c1a8f0036d9cc56d9ec566988d768..75e3d998ff9a1fb5771e99f86d30a4f6cdffb181 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -40,4 +40,4 @@ void nr_fill_rx_indication(fapi_nr_rx_indication_t *rx_ind, NR_UE_DLSCH_t *dlsch1, uint16_t n_pdus, UE_nr_rxtx_proc_t *proc, - void * typeSpecific ) {} + void *typeSpecific ) {} diff --git a/openair1/SIMULATION/NR_PHY/pbchsim.c b/openair1/SIMULATION/NR_PHY/pbchsim.c index ca696d4f9ced1a2cb044960b76f5d834deeb9075..0e648c945f8a5ea01aed0fbdbaa5d6c576076734 100644 --- a/openair1/SIMULATION/NR_PHY/pbchsim.c +++ b/openair1/SIMULATION/NR_PHY/pbchsim.c @@ -67,7 +67,10 @@ openair0_config_t openair0_cfg[MAX_CARDS]; uint8_t const nr_rv_round_map[4] = {0, 2, 3, 1}; uint64_t get_softmodem_optmask(void) {return 0;} -softmodem_params_t *get_softmodem_params(void) {return 0;} +static softmodem_params_t softmodem_params; +softmodem_params_t *get_softmodem_params(void) { + return &softmodem_params; +} void init_downlink_harq_status(NR_DL_UE_HARQ_t *dl_harq) {} @@ -171,8 +174,10 @@ int main(int argc, char **argv) uint8_t transmission_mode = 1,n_tx=1,n_rx=1; uint16_t Nid_cell=0; uint64_t SSB_positions=0x01; + int ssb_subcarrier_offset = 0; channel_desc_t *gNB2UE; + get_softmodem_params()->sa = 1; //uint8_t extended_prefix_flag=0; //int8_t interf1=-21,interf2=-21; @@ -214,7 +219,7 @@ int main(int argc, char **argv) exit_fun("[NR_PBCHSIM] Error, configuration module init failed\n"); } - while ((c = getopt (argc, argv, "F:g:hIL:m:M:n:N:o:P:r:R:s:S:x:y:z:")) != -1) { + while ((c = getopt (argc, argv, "F:g:hIL:m:M:n:N:o:O:P:r:R:s:S:x:y:z:")) != -1) { switch (c) { /*case 'f': write_output_file=1; @@ -312,6 +317,10 @@ int main(int argc, char **argv) Nid_cell = atoi(optarg); break; + case 'O': + ssb_subcarrier_offset = atoi(optarg); + break; + case 'o': cfo = atof(optarg); #ifdef DEBUG_NR_PBCHSIM @@ -414,6 +423,7 @@ int main(int argc, char **argv) printf("-n Number of frames to simulate\n"); printf("-N Nid_cell\n"); printf("-o Carrier frequency offset in Hz\n"); + printf("-O SSB subcarrier offset\n"); //printf("-O oversampling factor (1,2,4,8,16)\n"); //printf("-p Use extended prefix mode\n"); printf("-P PBCH phase, allowed values 0-3\n"); @@ -454,10 +464,11 @@ int main(int argc, char **argv) frame_parms->Nid_cell = Nid_cell; frame_parms->nushift = Nid_cell%4; frame_parms->ssb_type = nr_ssb_type_C; + frame_parms->freq_range = mu<2 ? nr_FR1 : nr_FR2; nr_phy_config_request_sim_pbchsim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); phy_init_nr_gNB(gNB,0,1); - nr_set_ssb_first_subcarrier(&gNB->gNB_config,frame_parms); + frame_parms->ssb_start_subcarrier = 12 * gNB->gNB_config.ssb_table.ssb_offset_point_a.value + ssb_subcarrier_offset; uint8_t n_hf = 0; int cyclic_prefix_type = NFAPI_CP_NORMAL; @@ -578,8 +589,12 @@ int main(int argc, char **argv) for (i=0; i<frame_parms->Lmax; i++) { if((SSB_positions >> i) & 0x01) { + const int sc_offset = frame_parms->freq_range == nr_FR1 ? ssb_subcarrier_offset<<mu : ssb_subcarrier_offset; + const int prb_offset = frame_parms->freq_range == nr_FR1 ? gNB->gNB_config.ssb_table.ssb_offset_point_a.value<<mu : gNB->gNB_config.ssb_table.ssb_offset_point_a.value << (mu - 2); msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33; msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i; + msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = sc_offset; + msgDataTx.ssb[i].ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = prb_offset; start_symbol = nr_get_ssb_start_symbol(frame_parms,i); int slot = start_symbol/14; @@ -722,8 +737,8 @@ int main(int argc, char **argv) if (ret<0) n_errors++; } else { - UE_nr_rxtx_proc_t proc={0}; - NR_UE_PDCCH_CONFIG phy_pdcch_config={0}; + UE_nr_rxtx_proc_t proc={0}; + NR_UE_PDCCH_CONFIG phy_pdcch_config={0}; UE->rx_offset=0; uint8_t ssb_index = 0; diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 33717c944dcd5e7eff84e679d9dbc456b10e080e..76776ce1101a9a049661bdab78e3885c551f60af 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -92,9 +92,17 @@ int oai_nfapi_nr_rach_indication(nfapi_nr_rach_indication_t *ind) { return(0); //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; -teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid, - transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) { -return 0; +teid_t newGtpuCreateTunnel(instance_t instance, + rnti_t rnti, + int incoming_bearer_id, + int outgoing_bearer_id, + teid_t outgoing_teid, + int qfi, + transport_layer_addr_t remoteAddr, + int port, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP) { + return 0; } int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) { diff --git a/openair1/SIMULATION/NR_PHY/pucchsim.c b/openair1/SIMULATION/NR_PHY/pucchsim.c index fda7c0dcba65f168cb1733d5b7c9bd061cc70700..0b159e36e9c5b103c9ad68cfc1f451ed43721658 100644 --- a/openair1/SIMULATION/NR_PHY/pucchsim.c +++ b/openair1/SIMULATION/NR_PHY/pucchsim.c @@ -27,6 +27,7 @@ #include <sys/mman.h> #include "common/config/config_userapi.h" #include "common/utils/load_module_shlib.h" +#include "common/utils/nr/nr_common.h" #include "common/utils/LOG/log.h" #include "common/ran_context.h" #include "PHY/types.h" @@ -391,45 +392,18 @@ int main(int argc, char **argv) nr_phy_config_request_sim(gNB,N_RB_DL,N_RB_DL,mu,Nid_cell,SSB_positions); phy_init_nr_gNB(gNB,0,0); - double fs,bw,scs,eps; - - if (mu == 1 && N_RB_DL == 217) { - fs = 122.88e6; - bw = 80e6; - scs = 30000; - } - else if (mu == 1 && N_RB_DL == 245) { - fs = 122.88e6; - bw = 90e6; - scs = 30000; - } - else if (mu == 1 && N_RB_DL == 273) { - fs = 122.88e6; - bw = 100e6; - scs = 30000; - } - else if (mu == 1 && N_RB_DL == 106) { - fs = 61.44e6; - bw = 40e6; - scs = 30000; - } - else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL); - - // cfo with respect to sub-carrier spacing - eps = cfo/scs; - - // computation of integer and fractional FO to compare with estimation results - int IFO; - if(eps!=0.0){ - printf("Introducing a CFO of %lf relative to SCS of %d kHz\n",eps,(int)(scs/1000)); - if (eps>0) - IFO=(int)(eps+0.5); - else - IFO=(int)(eps-0.5); - printf("FFO = %lf; IFO = %d\n",eps-IFO,IFO); - } + double fs,txbw,rxbw; + uint32_t samples; + + get_samplerate_and_bw(mu, + N_RB_DL, + frame_parms->threequarter_fs, + &fs, + &samples, + &txbw, + &rxbw); - UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, bw, DS_TDL,0, 0, 0, 0); + UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, fs, txbw, DS_TDL,0, 0, 0, 0); if (UE2gNB==NULL) { printf("Problem generating channel model. Exiting.\n"); @@ -478,9 +452,6 @@ int main(int argc, char **argv) memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); UE->frame_parms.nb_antennas_rx=1; - if(eps!=0.0) - UE->UE_fo_compensation = 1; // if a frequency offset is set then perform fo estimation and compensation - if (init_nr_ue_signal(UE, 1) != 0) { printf("Error at UE NR initialisation\n"); @@ -569,7 +540,7 @@ int main(int argc, char **argv) } random_channel(UE2gNB,0); - freq_channel(UE2gNB,N_RB_DL,2*N_RB_DL+1,scs/1000); + freq_channel(UE2gNB,N_RB_DL,2*N_RB_DL+1,15<<mu); for (int symb=0; symb<nrofSymbols; symb++) { int i0 = (startingSymbolIndex + symb)*gNB->frame_parms.ofdm_symbol_size; for (int re=0;re<N_RB_DL*12;re++) { @@ -641,6 +612,7 @@ int main(int argc, char **argv) pucch_pdu.initial_cyclic_shift = 0; pucch_pdu.start_symbol_index = startingSymbolIndex; pucch_pdu.prb_start = startingPRB; + pucch_pdu.prb_size = 1; pucch_pdu.bwp_start = 0; pucch_pdu.bwp_size = N_RB_DL; if (nrofSymbols>1) { @@ -705,7 +677,7 @@ int main(int argc, char **argv) pucch_pdu.second_hop_prb = N_RB_DL-1; } else pucch_pdu.freq_hop_flag = 0; - nr_decode_pucch2(gNB,nr_slot_tx,&uci_pdu,&pucch_pdu); + nr_decode_pucch2(gNB,nr_frame_tx,nr_slot_tx,&uci_pdu,&pucch_pdu); int csi_part1_bytes=pucch_pdu.bit_len_csi_part1>>3; if ((pucch_pdu.bit_len_csi_part1&7) > 0) csi_part1_bytes++; for (int i=0;i<csi_part1_bytes;i++) { diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index ad6992f6d073b95ae13890b689346569da3e5362..b19f062728bdf425e5cfb3a2b30b546b729c2128 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -28,6 +28,7 @@ #include "common/ran_context.h" #include "common/config/config_userapi.h" #include "common/utils/LOG/log.h" +#include "common/utils/nr/nr_common.h" #include "PHY/defs_gNB.h" #include "PHY/defs_nr_common.h" #include "PHY/defs_nr_UE.h" @@ -95,9 +96,17 @@ nfapi_ue_release_request_body_t release_rntis; //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; instance_t CUuniqInstance=0; -teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid, - transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) { -return 0; +teid_t newGtpuCreateTunnel(instance_t instance, + rnti_t rnti, + int incoming_bearer_id, + int outgoing_bearer_id, + teid_t outgoing_teid, + int qfi, + transport_layer_addr_t remoteAddr, + int port, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP) { + return 0; } int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti) { @@ -671,45 +680,23 @@ int main(int argc, char **argv) if (snr1set == 0) snr1 = snr0 + 10; - double sampling_frequency; - double bandwidth; - if (mu == 0 && N_RB_UL == 25 ) { - sampling_frequency = 7.68; - bandwidth = 5; - } - else if (mu == 1 && N_RB_UL == 273) { - sampling_frequency = 122.88; - bandwidth = 100; - } - else if (mu == 1 && N_RB_UL == 217) { - sampling_frequency = 122.88; - bandwidth = 80; - } - else if (mu == 1 && N_RB_UL == 106) { - sampling_frequency = 61.44; - bandwidth = 40; - } - else if (mu == 1 && N_RB_UL == 24) { - sampling_frequency = 15.36; - bandwidth = 10; - } - else if (mu == 3 && N_RB_UL == 32) { - sampling_frequency = 61.44; - bandwidth = 50; - } - else { - printf("Add N_RB_UL %d\n",N_RB_UL); - exit(-1); - } + double sampling_frequency, tx_bandwidth, rx_bandwidth; + uint32_t samples; + get_samplerate_and_bw(mu, + N_RB_DL, + openair0_cfg[0].threequarter_fs, + &sampling_frequency, + &samples, + &tx_bandwidth, + &rx_bandwidth); LOG_I( PHY,"++++++++++++++++++++++++++++++++++++++++++++++%i+++++++++++++++++++++++++++++++++++++++++",loglvl); - if (openair0_cfg[0].threequarter_fs == 1) sampling_frequency*=.75; UE2gNB = new_channel_desc_scm(n_tx, n_rx, channel_model, - sampling_frequency, - bandwidth, + sampling_frequency/1e6, + tx_bandwidth, DS_TDL, 0, 0, 0, 0); @@ -773,7 +760,7 @@ int main(int argc, char **argv) RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); for (i = 0; i < RC.nb_nr_macrlc_inst; i++) RC.nb_nr_mac_CC[i] = 1; - mac_top_init_gNB(); + mac_top_init_gNB(ngran_gNB); //gNB_MAC_INST* gNB_mac = RC.nrmac[0]; gNB_RRC_INST rrc; memset((void*)&rrc,0,sizeof(rrc)); @@ -811,9 +798,9 @@ int main(int argc, char **argv) gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; // common configuration - rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 0, 0, NULL); + rrc_mac_config_req_gNB(0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 0, 0, NULL); // UE dedicated configuration - rrc_mac_config_req_gNB(0,0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 1, + rrc_mac_config_req_gNB(0, conf.pdsch_AntennaPorts, n_rx, 0, 6, scc, &rrc.carrier.mib, rrc.carrier.siblock1, 1, secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, secondaryCellGroup); frame_parms->nb_antennas_tx = 1; frame_parms->nb_antennas_rx = n_rx; diff --git a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c index 31fe15a6de8ed377a4da95aaa50b82d7d8fa2f8a..12d50065fa83a4e2bc04d522ccbaa6612c31d720 100644 --- a/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c +++ b/openair1/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c @@ -165,7 +165,7 @@ void common_pucch_configuration(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int pucch_in int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) { int v_return = 0; - bool reset_harq = FALSE; + bool reset_harq = false; printf("%s", tst_separator); @@ -175,7 +175,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr common_pucch_configuration(ue, gNB_id, TST_PUCCH_COMMON_CONFIG_INDEX_KO); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -186,7 +186,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr printf("\n => Test : Error due to acknownlegment not set \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -194,7 +194,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr printf("\n => Test : Error due to DAI not set \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -202,7 +202,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr harq_status->vDAI_DL = NR_DL_MAX_DAI + 1; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -210,7 +210,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr harq_status->vDAI_DL = 0; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -218,7 +218,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr harq_status->send_harq_status = 1; /* ack ready to be send */ - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -228,7 +228,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr harq_status->vDAI_DL = 1; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -236,7 +236,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr printf("\n => Test : Error due to PUCCH format with multiple cells not already implemented \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -260,7 +260,7 @@ int test_pucch_basic_error(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pr int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) { int v_return = 0; - bool reset_harq = FALSE; + bool reset_harq = false; printf("%s", tst_separator); @@ -273,7 +273,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ printf("\n => Test : PUCCH format from common config in prach mode: one positive downlink ACKnowledgment \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } @@ -281,7 +281,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ printf("\n => Test : PUCCH format from common config in prach mode: one negative downlink ACKnowledgment \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } @@ -304,7 +304,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ printf("\n => Test : PUCCH format from common config in dedicated mode: two positive downlink ACKnowledgments \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } @@ -312,7 +312,7 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ printf("\n => Test : PUCCH format from common config in dedicated mode: one positive and one negative downlink ACKnowledgments \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } @@ -320,22 +320,22 @@ int test_pucch_common_config_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_ printf("\n => Test : PUCCH format from common config in dedicated mode: two negative downlink ACKnowledgments \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } harq_status->ack = DL_ACK; - reset_harq = TRUE; + reset_harq = true; printf("\n => Test : PUCCH format from common config in dedicated mode: no resource is found \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } printf("\n => Test : PUCCH format from common config in dedicated mode: no PUCCH after reset of pending harq ACKnowledgments \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -362,7 +362,7 @@ void init_pucch_dedicated_configuration(PHY_VARS_NR_UE *ue, uint8_t gNB_id) int i,j; /* set cell group parameters which are supported */ - ue->cell_group_config.physicalCellGroupConfig.harq_ACK_SpatialBundlingPUCCH = FALSE; + ue->cell_group_config.physicalCellGroupConfig.harq_ACK_SpatialBundlingPUCCH = false; ue->cell_group_config.physicalCellGroupConfig.pdsch_HARQ_ACK_Codebook = dynamic; ue->PDSCH_ServingCellConfig.codeBlockGroupTransmission = NULL; @@ -554,7 +554,7 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, #define TST_NB_STEP_SINGLE_TRANSPORT_BLOCK (4) int v_return = 0; - int reset_harq = FALSE; + int reset_harq = false; int dl_harq_pid[TST_NB_STEP_SINGLE_TRANSPORT_BLOCK] = {TST_DL_HARQ_PID_FIRST, TST_DL_HARQ_PID_SECOND, TST_DL_HARQ_PID_THIRD, TST_DL_HARQ_PID_FOURTH }; int pucch_resource_indicator[TST_NB_STEP_SINGLE_TRANSPORT_BLOCK][2] = { { 0, 4 }, { 1, 0 } , { 1, 3 } , { 5, 7 } }; NR_UE_HARQ_STATUS_t *harq_status; @@ -575,7 +575,7 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, printf("\n => Test : PUCCH format from dedicated config : pucch resource indicator is invalid \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { v_return = -1; } @@ -595,14 +595,14 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, /* reset ack context on last test */ if ((i == (TST_NB_STEP_SINGLE_TRANSPORT_BLOCK-1)) && (j == 1)) { - reset_harq = TRUE; + reset_harq = true; } harq_status->pucch_resource_indicator = pucch_resource_indicator[i][j]; printf("\n => Test : PUCCH format from dedicated config with 1 transport block : with %d downlink ACKnowledgments and pucch resource indicator %d \n", i+1, pucch_resource_indicator[i][j]); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } } @@ -627,11 +627,11 @@ int test_pucch_dedicated_single_transport_block(PHY_VARS_NR_UE *ue, int gNB_id, harq_status->pucch_resource_indicator = pucch_resource_indicator[i][0]; } - reset_harq = TRUE; + reset_harq = true; printf("\n => Test : PUCCH format from dedicated config with 1 transport block and missed PDSCH : with %d downlink ACKnowledgments and pucch resource indicator %d \n", i+1, pucch_resource_indicator[3][0]); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { v_return = -1; } @@ -659,7 +659,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE #define TST_NB_STEP_TWO_TRANSPORT_BLOCKS (4) int v_return = 0; - int reset_harq = FALSE; + int reset_harq = false; int dl_harq_pid[TST_NB_STEP_TWO_TRANSPORT_BLOCKS] = {TST_DL_HARQ_PID_FIRST, TST_DL_HARQ_PID_SECOND, TST_DL_HARQ_PID_THIRD, TST_DL_HARQ_PID_FOURTH }; int pucch_resource_indicator[TST_NB_STEP_TWO_TRANSPORT_BLOCKS][2] = { { 0, 1 }, { 3, 7 } , { 2 , 4 } , { 4 , 6 } }; NR_UE_HARQ_STATUS_t *harq_status; @@ -694,7 +694,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE /* reset ack context on last test */ if ((i == (TST_NB_STEP_TWO_TRANSPORT_BLOCKS-1)) && (j == 1)) { - reset_harq = TRUE; + reset_harq = true; } harq_status = &ue->dlsch[proc->thread_id][gNB_id][0]->harq_processes[dl_harq_pid[i]].harq_ack; @@ -703,7 +703,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE printf("\n => Test : PUCCH format from dedicated config with 2 transport blocks : with %d downlink ACKnowledgments and pucch resource indicator %d \n", i+1, pucch_resource_indicator[i][j]); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -714,7 +714,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE /* some transport blocks have been missed and they need to be nack by UE in order to be retransmitted by the network */ /* here first and third block receptions have been missed */ - reset_harq = TRUE; + reset_harq = true; for (int i = 1; i < TST_NB_STEP_TWO_TRANSPORT_BLOCKS; i = i + 1) { @@ -743,7 +743,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE printf("\n => Test : PUCCH format from dedicated config with 2 transport blocks and 1 missed PDSCH : with %d downlink ACKnowledgments and pucch resource indicator %d \n", 4, pucch_resource_indicator[3][0]); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -775,7 +775,7 @@ int test_pucch_dedicated_two_transport_blocks(PHY_VARS_NR_UE *ue, int gNB_id, UE } } - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -907,7 +907,7 @@ int test_sr_alone_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *p tst_scheduling_request_payload = 0; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != FALSE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != false) { printf("Test fail \n"); v_return = -1; } @@ -916,7 +916,7 @@ int test_sr_alone_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *p tst_scheduling_request_payload = 1; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -929,7 +929,7 @@ int test_sr_alone_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *p tst_scheduling_request_payload = 1; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -958,7 +958,7 @@ int test_sr_alone_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *p int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) { int v_return = 0; - int reset_harq = 0; + bool reset_harq = false; int sr_config_id = 0; int sr_resource_id = 0; int sr_offset = 0; @@ -988,7 +988,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro tst_scheduling_request_payload = 0; /* set sr payload */ - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -997,7 +997,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro tst_scheduling_request_payload = 1; /* set sr payload */ - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1006,7 +1006,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro harq_status->pucch_resource_indicator = pucch_resource_indicator[1]; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1027,7 +1027,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro tst_scheduling_request_payload = 1; /* set sr payload */ - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1035,9 +1035,9 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro printf("\n => Test : PUCCH format from dedicated config with a positive scheduling request and two positive acks \n"); harq_status->pucch_resource_indicator = pucch_resource_indicator[1]; - reset_harq = TRUE; + reset_harq = true; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1065,7 +1065,7 @@ int test_sr_ack_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *pro int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) { int v_return = 0; - int reset_harq = FALSE; + int reset_harq = false; int sr_config_id = 0; int sr_resource_id = 0; int sr_offset = 0; @@ -1079,7 +1079,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) printf("\n => Test : PUCCH format from dedicated config with CSI alone \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1102,7 +1102,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) ue->pucch_config_dedicated_nr[gNB_id].formatConfig[2-1]->simultaneousHARQ_ACK_CSI = enable_feature; /* format 2 */ - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1115,9 +1115,9 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) tst_scheduling_request_payload = 0; /* set sr payload */ - reset_harq = TRUE; + reset_harq = true; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1126,7 +1126,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) harq_status->pucch_resource_indicator = pucch_resource_indicator[4]; - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } @@ -1135,7 +1135,7 @@ int test_csi_dedicated(PHY_VARS_NR_UE *ue, int gNB_id, UE_nr_rxtx_proc_t *proc) printf("\n => Test : PUCCH format from dedicated config with positive SR and CSI \n"); - if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != TRUE) { + if (pucch_procedures_ue_nr(ue, gNB_id, proc, reset_harq) != true) { printf("Test fail \n"); v_return = -1; } diff --git a/openair1/SIMULATION/TOOLS/rangen_double.c b/openair1/SIMULATION/TOOLS/rangen_double.c index 82b1557a5bf73a86fdf3f2b9ceb8f1ac5ee42623..0ba9e196b1349100f990ac4620a509cfaa246580 100644 --- a/openair1/SIMULATION/TOOLS/rangen_double.c +++ b/openair1/SIMULATION/TOOLS/rangen_double.c @@ -42,7 +42,6 @@ void randominit(unsigned seed_init) { int i; // this need to be integrated with the existing rng, like taus: navid - printf("Initializing random number generator, seed %x\n",seed_init); if (seed_init == 0) { srand((unsigned)time(NULL)); @@ -51,6 +50,7 @@ void randominit(unsigned seed_init) } else { seed = seed_init; } + printf("Initializing random number generator, seed %x\n",seed); if (seed % 2 == 0) seed += 1; /* seed and mod are relative prime */ diff --git a/openair2/COMMON/commonDef.h b/openair2/COMMON/commonDef.h index b37230cdd45ffbd9154556bb4ed5aa46d7185af6..e18db881f04940f74e4bfeb6a4e9ac7e1b8cfc6a 100644 --- a/openair2/COMMON/commonDef.h +++ b/openair2/COMMON/commonDef.h @@ -43,27 +43,6 @@ Description Contains global common definitions #include <stddef.h> #include <stdbool.h> -/* boolean_t is also defined in openair2/COMMON/platform_types.h - * let's protect potential redefinition - */ - -#ifndef _BOOLEAN_T_DEFINED_ -#define _BOOLEAN_T_DEFINED_ - -typedef signed char boolean_t; - -#if !defined(TRUE) -#define TRUE (boolean_t)0x01 -#endif - -#if !defined(FALSE) -#define FALSE (boolean_t)0x00 -#endif - -#define BOOL_NOT(b) (b^TRUE) - -#endif /* _BOOLEAN_T_DEFINED_ */ - #define NAS_UE_ID_FMT "0x%06x" /****************************************************************************/ diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index 0e857f3a83cb5cb6fd9843728359e6748117ee6c..f28e0e5ddfc1989db3329a74feef9e487e94f279 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -46,6 +46,8 @@ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req ) MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_req) MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_resp) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_req) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_modification_resp) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 5e5b4c37d3f9b46b3ca35f27ab59157231259807..cbc4d1c6f2dedc169e7c7fd64e97d6a90a09d833 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -23,6 +23,7 @@ #define F1AP_MESSAGES_TYPES_H_ #include "rlc.h" +#include "s1ap_messages_types.h" //-------------------------------------------------------------------------------------------// // Defines to access message fields. @@ -39,15 +40,15 @@ #define F1AP_INITIAL_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_initial_ul_rrc_message #define F1AP_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ul_rrc_message #define F1AP_UE_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_req -#define F1AP_UE_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_resp +#define F1AP_UE_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_resp #define F1AP_UE_CONTEXT_RELEASE_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_resp +#define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req #define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp #define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail #define F1AP_DL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_dl_rrc_message #define F1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req #define F1AP_UE_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_release_req -#define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req /* Length of the transport layer address string * 160 bits / 8 bits by char. @@ -61,7 +62,6 @@ #define F1AP_MAX_NO_OF_TNL_ASSOCIATIONS 32 #define F1AP_MAX_NO_UE_ID 1024 -#define F1AP_MAX_DU2CU_RRC_LENGTH 1024 typedef struct f1ap_net_ip_address_s { unsigned ipv4:1; @@ -309,7 +309,7 @@ typedef struct f1ap_initial_ul_rrc_message_s { uint16_t crnti; uint8_t *rrc_container; int rrc_container_length; - char du2cu_rrc_container[F1AP_MAX_DU2CU_RRC_LENGTH]; + uint8_t *du2cu_rrc_container; int du2cu_rrc_container_length; } f1ap_initial_ul_rrc_message_t; @@ -345,6 +345,35 @@ typedef struct f1ap_rb_failed_to_be_setup_s { long rb_id; } f1ap_rb_failed_to_be_setup_t; +typedef struct cu_to_du_rrc_information_s { + uint8_t * cG_ConfigInfo; + uint32_t cG_ConfigInfo_length; + uint8_t * uE_CapabilityRAT_ContainerList; + uint32_t uE_CapabilityRAT_ContainerList_length; + uint8_t * measConfig; + uint32_t measConfig_length; +}cu_to_du_rrc_information_t; + +typedef struct du_to_du_rrc_information_s { + uint8_t * cellGroupConfig; + uint8_t cellGroupConfig_length; + uint8_t * measGapConfig; + uint8_t measGapConfig_length; + uint8_t * requestedP_MaxFR1; + uint8_t requestedP_MaxFR1_length; +}du_to_cu_rrc_information_t; + +typedef enum QoS_information_e { + NG_RAN_QoS = 0, + EUTRAN_QoS = 1, +} QoS_information_t; + +typedef enum ReconfigurationCompl_e { + RRCreconf_info_not_present = 0, + RRCreconf_failure = 1, + RRCreconf_success = 2, +} ReconfigurationCompl_t; + typedef struct f1ap_ue_context_setup_s { uint32_t gNB_CU_ue_id; // BK: need to replace by use from rnti uint32_t gNB_DU_ue_id; @@ -357,40 +386,27 @@ typedef struct f1ap_ue_context_setup_s { uint8_t servCellIndex; uint8_t *cellULConfigured; uint32_t servCellId; - uint8_t *cu_to_du_rrc_information; + cu_to_du_rrc_information_t *cu_to_du_rrc_information; uint8_t cu_to_du_rrc_information_length; - uint8_t *du_to_cu_rrc_information; - uint8_t du_to_cu_rrc_information_length; - f1ap_drb_to_be_setup_t *drbs_to_be_setup; // BK: need to replace by s1ap_initial_context_setup_req - uint8_t drbs_to_be_setup_length; // BK: need to replace by s1ap_initial_context_setup_req + //uint8_t *du_to_cu_rrc_information; + du_to_cu_rrc_information_t *du_to_cu_rrc_information; + uint32_t du_to_cu_rrc_information_length; + f1ap_drb_to_be_setup_t *drbs_to_be_setup; + uint8_t drbs_to_be_setup_length; + f1ap_drb_to_be_setup_t *drbs_to_be_modified; + uint8_t drbs_to_be_modified_length; + QoS_information_t QoS_information_type; uint8_t drbs_failed_to_be_setup_length; f1ap_rb_failed_to_be_setup_t *drbs_failed_to_be_setup; f1ap_srb_to_be_setup_t *srbs_to_be_setup; uint8_t srbs_to_be_setup_length; uint8_t srbs_failed_to_be_setup_length; f1ap_rb_failed_to_be_setup_t *srbs_failed_to_be_setup; - s1ap_initial_context_setup_req_t *s1ap_initial_context_setup_req; - // coniatner for the rrc_eNB_generate_SecurityModeCommand message + ReconfigurationCompl_t ReconfigComplOutcome; uint8_t *rrc_container; int rrc_container_length; } f1ap_ue_context_setup_t; -typedef struct f1ap_ue_context_setup_resp_s { - uint32_t gNB_CU_ue_id; // BK: need to replace by use from rnti - uint32_t gNB_DU_ue_id; - uint16_t rnti; - uint8_t du_to_cu_rrc_information[1024 /*Arbitrarily big enough*/]; - uint32_t du_to_cu_rrc_information_length; - f1ap_drb_to_be_setup_t *drbs_setup; // BK: need to replace by s1ap_initial_context_setup_req - uint8_t drbs_setup_length; // BK: need to replace by s1ap_initial_context_setup_req - f1ap_srb_to_be_setup_t *srbs_setup; - uint8_t srbs_setup_length; - uint8_t srbs_failed_to_be_setup_length; - f1ap_rb_failed_to_be_setup_t *srbs_failed_to_be_setup; - uint8_t drbs_failed_to_be_setup_length; - f1ap_rb_failed_to_be_setup_t *drbs_failed_to_be_setup; -} f1ap_ue_context_setup_resp_t; - typedef enum F1ap_Cause_e { F1AP_CAUSE_NOTHING, /* No components present */ F1AP_CAUSE_RADIO_NETWORK, diff --git a/openair2/COMMON/gtpv1_u_messages_def.h b/openair2/COMMON/gtpv1_u_messages_def.h index 44e9d4fbdf2b2243e48c87b7c52dabaf2a13f72d..e0e5db5b7f72bd0adf45c9175b1fe9f376c4664d 100644 --- a/openair2/COMMON/gtpv1_u_messages_def.h +++ b/openair2/COMMON/gtpv1_u_messages_def.h @@ -27,4 +27,5 @@ MESSAGE_DEF(GTPV1U_ENB_END_MARKER_REQ, MESSAGE_PRIORITY_MED, gtpv1u_enb_end MESSAGE_DEF(GTPV1U_ENB_END_MARKER_IND, MESSAGE_PRIORITY_MED, gtpv1u_enb_end_marker_ind_t, Gtpv1uEndMarkerInd) MESSAGE_DEF(GTPV1U_REQ, MESSAGE_PRIORITY_MED, Gtpv1uReq, gtpv1uReq) -MESSAGE_DEF(GTPV1U_GNB_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_tunnel_data_req_t, NRGtpv1uTunnelDataReq) +MESSAGE_DEF(GTPV1U_GNB_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, gtpv1u_gnb_tunnel_data_req_t, NRGtpv1uTunnelDataReq) +MESSAGE_DEF(GTPV1U_DU_BUFFER_REPORT_REQ, MESSAGE_PRIORITY_MED, gtpv1u_DU_buffer_report_req_t, NRGtpv1uBufferReportReq) diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 096f0f4697276ac094d21f861785ffa0e07b5620..7758395ee43fd2274cfbefdf998348c518c4e9f8 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -39,6 +39,8 @@ #define GTPV1U_GNB_TUNNEL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uTunnelDataReq +#define GTPV1U_DU_BUFFER_REPORT_REQ(mSGpTR) (mSGpTR)->ittiMsg.NRGtpv1uBufferReportReq + #define GTPV1U_ALL_TUNNELS_TEID (teid_t)0xFFFFFFFF typedef struct gtpv1u_enb_create_x2u_tunnel_req_s { @@ -179,6 +181,7 @@ typedef struct gtpv1u_gnb_create_tunnel_req_s { int num_tunnels; //teid_t upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier teid_t outgoing_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; + int outgoing_qfi[NR_GTPV1U_MAX_BEARERS_PER_UE]; pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; ebi_t incoming_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; //ebi_t outgoing_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; @@ -213,4 +216,10 @@ typedef struct gtpv1u_gnb_tunnel_data_req_s { pdusessionid_t pdusession_id; } gtpv1u_gnb_tunnel_data_req_t; +typedef struct gtpv1u_DU_buffer_report_req_s { + uint32_t buffer_availability; + rnti_t rnti; + pdusessionid_t pdusession_id; +} gtpv1u_DU_buffer_report_req_t; + #endif /* GTPV1_U_MESSAGES_TYPES_H_ */ diff --git a/openair2/COMMON/mac_rlc_primitives.h b/openair2/COMMON/mac_rlc_primitives.h index 4e3e22781c5fbb9494c23f271ddfe543bae2be2f..3d6dcc810035471bfc87fb8d97763ce1e427abb8 100644 --- a/openair2/COMMON/mac_rlc_primitives.h +++ b/openair2/COMMON/mac_rlc_primitives.h @@ -145,7 +145,7 @@ struct mac_tx_tb_management { struct mac_rx_tb_management { unsigned char *data_ptr; tb_size_t tb_size; // in bits - boolean_t valid_checksum; + bool valid_checksum; unsigned char first_bit; // 0 if data starts on byte boundary(b7), 1 if b6, 2 if b5, etc }; diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 67300da308b92ed05e7f901ae15436794f675826..f2297219936779186ef88ea245bc0016e6871221 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -32,35 +32,12 @@ #if !defined(NAS_NETLINK) #include <stdint.h> +#include <stdbool.h> #else #include <linux/types.h> typedef void * intptr_t; #endif -//----------------------------------------------------------------------------- -// GENERIC TYPES -//----------------------------------------------------------------------------- - -/* boolean_t is also defined in openair2/COMMON/commonDef.h, - * let's protect potential redefinition - */ -#ifndef _BOOLEAN_T_DEFINED_ - #define _BOOLEAN_T_DEFINED_ - - typedef signed char boolean_t; - - #if !defined(TRUE) - #define TRUE (boolean_t)0x01 - #endif - - #if !defined(FALSE) - #define FALSE (boolean_t)0x00 - #endif - - #define BOOL_NOT(b) (b^TRUE) - -#endif /* _BOOLEAN_T_DEFINED_ */ - //----------------------------------------------------------------------------- // GENERIC ACCESS STRATUM TYPES //----------------------------------------------------------------------------- @@ -77,25 +54,25 @@ typedef int16_t smodule_id_t; typedef long rb_id_t; typedef long srb_id_t; -typedef boolean_t MBMS_flag_t; -#define MBMS_FLAG_NO FALSE -#define MBMS_FLAG_YES TRUE +typedef bool MBMS_flag_t; +#define MBMS_FLAG_NO false +#define MBMS_FLAG_YES true -typedef boolean_t eNB_flag_t; -#define ENB_FLAG_NO FALSE -#define ENB_FLAG_YES TRUE +typedef bool eNB_flag_t; +#define ENB_FLAG_NO false +#define ENB_FLAG_YES true -typedef boolean_t gNB_flag_t; -#define GNB_FLAG_NO FALSE -#define GNB_FLAG_YES TRUE +typedef bool gNB_flag_t; +#define GNB_FLAG_NO false +#define GNB_FLAG_YES true -typedef boolean_t srb_flag_t; -#define SRB_FLAG_NO FALSE -#define SRB_FLAG_YES TRUE +typedef bool srb_flag_t; +#define SRB_FLAG_NO false +#define SRB_FLAG_YES true -typedef boolean_t sl_discovery_flag_t; -#define SL_DISCOVERY_FLAG_NO FALSE -#define SL_DISCOVERY_FLAG_YES TRUE +typedef bool sl_discovery_flag_t; +#define SL_DISCOVERY_FLAG_NO false +#define SL_DISCOVERY_FLAG_YES true typedef enum link_direction_e { UNKNOWN_DIR = 0, @@ -152,8 +129,8 @@ typedef uint16_t rlc_usn_t; typedef int32_t rlc_buffer_occupancy_t; typedef signed int rlc_op_status_t; -#define SDU_CONFIRM_NO FALSE -#define SDU_CONFIRM_YES TRUE +#define SDU_CONFIRM_NO false +#define SDU_CONFIRM_YES true //----------------------------------------------------------------------------- // PDCP TYPES //----------------------------------------------------------------------------- @@ -242,7 +219,7 @@ typedef struct protocol_ctxt_s { frame_t frame; /*!< \brief LTE frame number.*/ sub_frame_t subframe; /*!< \brief LTE sub frame number.*/ eNB_index_t eNB_index; /*!< \brief valid for UE indicating the index of connected eNB(s) */ - boolean_t brOption; + bool brOption; } protocol_ctxt_t; // warning time hardcoded #define PROTOCOL_CTXT_TIME_MILLI_SECONDS(CtXt_h) ((CtXt_h)->frame*10+(CtXt_h)->subframe) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 67b0b610ccafcc35d8643016c6a1630adc0527ff..18e7c4bd18b08296e2d567eb214e03f3b0d81374 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -417,7 +417,6 @@ typedef struct NRRrcConfigurationReq_s { uint8_t num_plmn; NR_ServingCellConfigCommon_t *scc; NR_ServingCellConfig_t *scd; - int ssb_SubcarrierOffset; int sib1_tda; rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts; int pusch_AntennaPorts; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index f4550f63a15b3e067da94975db420b3c57d221af..00ffd4cc1342776915c8608a364476345c7212f9 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -583,9 +583,9 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PRACH_HIGH_SPEED); else if (strcmp(ccparams_lte.prach_high_speed, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = true; } else if (strcmp(ccparams_lte.prach_high_speed, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].prach_high_speed = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n", @@ -689,9 +689,9 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_ENABLE64QAM); else if (strcmp(ccparams_lte.pusch_enable64QAM, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = true; } else if (strcmp(ccparams_lte.pusch_enable64QAM, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_enable64QAM = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n", @@ -702,9 +702,9 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN); else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled = true; } else if (strcmp(ccparams_lte.pusch_groupHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_groupHoppingEnabled= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n", @@ -723,9 +723,9 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u define %s: ENABLE,DISABLE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN); else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = true; } else if (strcmp(ccparams_lte.pusch_sequenceHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].pusch_sequenceHoppingEnabled = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n", @@ -766,15 +766,15 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].phich_duration,ccparams_lte.phich_duration); if (strcmp(ccparams_lte.srs_enable, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= true; } else if (strcmp(ccparams_lte.srs_enable, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", RC.config_file_name, i, ccparams_lte.srs_enable); - if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable== TRUE) { + if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_enable== true) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_BandwidthConfig= ccparams_lte.srs_BandwidthConfig; if ((ccparams_lte.srs_BandwidthConfig < 0) || @@ -791,18 +791,18 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RC.config_file_name, i, ccparams_lte.srs_SubframeConfig); if (strcmp(ccparams_lte.srs_ackNackST, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= true; } else if (strcmp(ccparams_lte.srs_ackNackST, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_ackNackST= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", RC.config_file_name, i, ccparams_lte.srs_ackNackST); if (strcmp(ccparams_lte.srs_MaxUpPts, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= true; } else if (strcmp(ccparams_lte.srs_MaxUpPts, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].srs_MaxUpPts= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n", @@ -921,7 +921,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { RC.config_file_name, i, ccparams_lte.rach_numberOfRA_Preambles); if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= true; RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_sizeOfRA_PreamblesGroupA= (ccparams_lte.rach_sizeOfRA_PreamblesGroupA/4)-1; if ((ccparams_lte.rach_numberOfRA_Preambles <4) || @@ -976,7 +976,7 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n", RC.config_file_name, i, ccparams_lte.rach_messagePowerOffsetGroupB); } else if (strcmp(ccparams_lte.rach_preamblesGroupAConfig, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].rach_preamblesGroupAConfig= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n", @@ -1254,9 +1254,9 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) { "Failed to parse eNB configuration file %s, enb %u define %s: TRUE,FALSE!\n", RC.config_file_name, i, ENB_CONFIG_STRING_MBMS_DEDICATED_SERVING_CELL); else if (strcmp(ccparams_lte.mbms_dedicated_serving_cell, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = true; } else if (strcmp(ccparams_lte.mbms_dedicated_serving_cell, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig[j].mbms_dedicated_serving_cell = false; } else { AssertFatal (0, "Failed to parse eNB configuration file %s, enb %u unknown value \"%s\" for mbms_dedicated_serving_cell choice: TRUE or FALSE !\n", diff --git a/openair2/ENB_APP/enb_config_eMTC.c b/openair2/ENB_APP/enb_config_eMTC.c index 2e71f17e9d871365b39eec6bea908caaf01c0bb3..e4ff458886b06fe99437de821d834c7a33e090dd 100644 --- a/openair2/ENB_APP/enb_config_eMTC.c +++ b/openair2/ENB_APP/enb_config_eMTC.c @@ -61,18 +61,18 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in if (!strcmp(eMTCconfig->cellSelectionInfoCE_r13, "ENABLE")) { - RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = true; RRC_CONFIGURATION_REQ(msg_p).q_RxLevMinCE_r13[cc_idx]= eMTCconfig->q_RxLevMinCE_r13; // RRC_CONFIGURATION_REQ(msg_p).q_QualMinRSRQ_CE_r13[cc_idx]= calloc(1, sizeof(long)); // *RRC_CONFIGURATION_REQ(msg_p).q_QualMinRSRQ_CE_r13[cc_idx]= q_QualMinRSRQ_CE_r13; } else { - RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = FALSE; + RRC_CONFIGURATION_REQ(msg_p).cellSelectionInfoCE_r13[cc_idx] = false; } if (!strcmp(eMTCconfig->bandwidthReducedAccessRelatedInfo_r13, "ENABLE")) { - RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = true; @@ -106,7 +106,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in } } else { - RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = FALSE; + RRC_CONFIGURATION_REQ(msg_p).bandwidthReducedAccessRelatedInfo_r13[cc_idx] = false; } char schedulingInfoBrPath[MAX_OPTNAME_SIZE * 2]; @@ -127,10 +127,10 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = CALLOC(1, sizeof(BOOLEAN_t)); if (!strcmp(eMTCconfig->fdd_DownlinkOrTddSubframeBitmapBR_r13, "subframePattern40-r13")) { - *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = FALSE; + *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = false; RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_val_r13[cc_idx] = eMTCconfig->fdd_DownlinkOrTddSubframeBitmapBR_val_r13; } else { - *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = TRUE; + *RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_r13[cc_idx] = true; RRC_CONFIGURATION_REQ(msg_p).fdd_DownlinkOrTddSubframeBitmapBR_val_r13[cc_idx] = eMTCconfig->fdd_DownlinkOrTddSubframeBitmapBR_val_r13; } @@ -156,18 +156,18 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in if (!strcmp(eMTCconfig->freqHoppingParametersDL_r13, "ENABLE")) { - RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = true; if (!strcmp(eMTCconfig->interval_DLHoppingConfigCommonModeA_r13, "interval-TDD-r13")) - RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = FALSE; + RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = false; else - RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13[cc_idx] = true; RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeA_r13_val[cc_idx] = eMTCconfig->interval_DLHoppingConfigCommonModeA_r13_val; if (!strcmp(eMTCconfig->interval_DLHoppingConfigCommonModeB_r13, "interval-TDD-r13")) - RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = FALSE; + RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = false; else - RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13[cc_idx] = true; RRC_CONFIGURATION_REQ(msg_p).interval_DLHoppingConfigCommonModeB_r13_val[cc_idx] = eMTCconfig->interval_DLHoppingConfigCommonModeB_r13_val; RRC_CONFIGURATION_REQ(msg_p).mpdcch_pdsch_HoppingNB_r13[cc_idx] = calloc(1, sizeof(long)); @@ -188,7 +188,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in } else { - RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = FALSE; + RRC_CONFIGURATION_REQ(msg_p).freqHoppingParametersDL_r13[cc_idx] = false; } /** ------------------------------SIB2/3 BR------------------------------------------ */ @@ -213,9 +213,9 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", config_fname, cell_idx,ENB_CONFIG_STRING_PRACH_HIGH_SPEED); else if (strcmp(eMTCconfig->ccparams.prach_high_speed, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_high_speed = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_high_speed = true; } else if (strcmp(eMTCconfig->ccparams.prach_high_speed, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_high_speed = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].prach_high_speed = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for prach_config choice: ENABLE,DISABLE !\n", @@ -310,9 +310,9 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", config_fname, cell_idx,ENB_CONFIG_STRING_PUSCH_ENABLE64QAM); else if (strcmp(eMTCconfig->ccparams.pusch_enable64QAM, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_enable64QAM = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_enable64QAM = true; } else if (strcmp(eMTCconfig->ccparams.pusch_enable64QAM, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_enable64QAM = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_enable64QAM = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_enable64QAM choice: ENABLE,DISABLE!\n", @@ -323,9 +323,9 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", config_fname, cell_idx,ENB_CONFIG_STRING_PUSCH_GROUP_HOPPING_EN); else if (strcmp(eMTCconfig->ccparams.pusch_groupHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_groupHoppingEnabled = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_groupHoppingEnabled = true; } else if (strcmp(eMTCconfig->ccparams.pusch_groupHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_groupHoppingEnabled= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_groupHoppingEnabled= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_groupHoppingEnabled choice: ENABLE,DISABLE!\n", @@ -343,9 +343,9 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d define %s: ENABLE,DISABLE!\n", config_fname, cell_idx,ENB_CONFIG_STRING_PUSCH_SEQUENCE_HOPPING_EN); else if (strcmp(eMTCconfig->ccparams.pusch_sequenceHoppingEnabled, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_sequenceHoppingEnabled = TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_sequenceHoppingEnabled = true; } else if (strcmp(eMTCconfig->ccparams.pusch_sequenceHoppingEnabled, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_sequenceHoppingEnabled = FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pusch_sequenceHoppingEnabled = false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_sequenceHoppingEnabled choice: ENABLE,DISABLE!\n", @@ -385,15 +385,15 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].phich_duration,eMTCconfig->ccparams.phich_duration); if (strcmp(eMTCconfig->ccparams.srs_enable, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable= true; } else if (strcmp(eMTCconfig->ccparams.srs_enable, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", config_fname, cell_idx,eMTCconfig->ccparams.srs_enable); - if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable== TRUE) { + if (RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_enable== true) { RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_BandwidthConfig= eMTCconfig->ccparams.srs_BandwidthConfig; if ((eMTCconfig->ccparams.srs_BandwidthConfig < 0) || (eMTCconfig->ccparams.srs_BandwidthConfig >7)) @@ -408,18 +408,18 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in config_fname, cell_idx,eMTCconfig->ccparams.srs_SubframeConfig); if (strcmp(eMTCconfig->ccparams.srs_ackNackST, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_ackNackST= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_ackNackST= true; } else if (strcmp(eMTCconfig->ccparams.srs_ackNackST, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_ackNackST= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_ackNackST= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_BandwidthConfig choice: ENABLE,DISABLE !\n", config_fname, cell_idx,eMTCconfig->ccparams.srs_ackNackST); if (strcmp(eMTCconfig->ccparams.srs_MaxUpPts, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_MaxUpPts= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_MaxUpPts= true; } else if (strcmp(eMTCconfig->ccparams.srs_MaxUpPts, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_MaxUpPts= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].srs_MaxUpPts= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for srs_MaxUpPts choice: ENABLE,DISABLE !\n", @@ -535,7 +535,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in config_fname, cell_idx,eMTCconfig->ccparams.rach_numberOfRA_Preambles); if (strcmp(eMTCconfig->ccparams.rach_preamblesGroupAConfig, "ENABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preamblesGroupAConfig= TRUE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preamblesGroupAConfig= true; RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_sizeOfRA_PreamblesGroupA= (eMTCconfig->ccparams.rach_sizeOfRA_PreamblesGroupA/4)-1; if ((eMTCconfig->ccparams.rach_numberOfRA_Preambles <4) || (eMTCconfig->ccparams.rach_numberOfRA_Preambles>60) || ((eMTCconfig->ccparams.rach_numberOfRA_Preambles&3)!=0)) @@ -588,7 +588,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n", config_fname, cell_idx,eMTCconfig->ccparams.rach_messagePowerOffsetGroupB); } else if (strcmp(eMTCconfig->ccparams.rach_preamblesGroupAConfig, "DISABLE") == 0) { - RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preamblesGroupAConfig= FALSE; + RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].rach_preamblesGroupAConfig= false; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_preamblesGroupAConfig choice: ENABLE,DISABLE !\n", @@ -847,14 +847,14 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in if (!strcmp(eMTCconfig->prach_ConfigCommon_v1310, "ENABLE")) { - RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = TRUE; + RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = true; RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = calloc(1, sizeof(BOOLEAN_t)); if (!strcmp(eMTCconfig->mpdcch_startSF_CSS_RA_r13, "tdd-r13")) { - *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = FALSE; + *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = false; } else { - *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = TRUE; + *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].mpdcch_startSF_CSS_RA_r13 = true; } if (!strcmp(eMTCconfig->mpdcch_startSF_CSS_RA_r13_val, "v1")) { @@ -882,7 +882,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_HoppingOffset_r13 = calloc(1, sizeof(long)); *RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_HoppingOffset_r13 = eMTCconfig->prach_HoppingOffset_r13; } else { - RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = FALSE; + RRC_CONFIGURATION_REQ(msg_p).radioresourceconfig_BR[cc_idx].prach_ConfigCommon_v1310 = false; } @@ -1169,7 +1169,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in /** PCCH CONFIG V1310 */ - RRC_CONFIGURATION_REQ(msg_p).pcch_config_v1310[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).pcch_config_v1310[cc_idx] = true; RRC_CONFIGURATION_REQ(msg_p).paging_narrowbands_r13[cc_idx] = eMTCconfig->paging_narrowbands_r13; RRC_CONFIGURATION_REQ(msg_p).mpdcch_numrepetition_paging_r13[cc_idx] = eMTCconfig->mpdcch_numrepetition_paging_r13; @@ -1220,7 +1220,7 @@ void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, in /** SIB2 FREQ HOPPING PARAMETERS R13 */ - RRC_CONFIGURATION_REQ(msg_p).sib2_freq_hoppingParameters_r13_exists[cc_idx] = TRUE; + RRC_CONFIGURATION_REQ(msg_p).sib2_freq_hoppingParameters_r13_exists[cc_idx] = true; char sib2FreqHoppingParametersR13Path[MAX_OPTNAME_SIZE*2 + 16]; sprintf(sib2FreqHoppingParametersR13Path, "%s.%s", brparamspath, ENB_CONFIG_STRING_SIB2_FREQ_HOPPINGPARAMETERS_R13); diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 9926ec9e20639d356b5e1ccdc6cf13b0a5cf83a4..3113c07798168a9aecb1f44218fd9162f39f9362 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -127,7 +127,7 @@ int flexran_get_mac_ue_id_rnti(mid_t mod_id, rnti_t rnti) { /* get the (active) UE with RNTI i */ for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) { - if (RC.mac[mod_id]->UE_info.active[n] == TRUE + if (RC.mac[mod_id]->UE_info.active[n] == true && rnti == UE_RNTI(mod_id, n)) { return n; } @@ -143,7 +143,7 @@ int flexran_get_mac_ue_id(mid_t mod_id, int i) { /* get the (i+1)'th active UE */ for (n = 0; n < MAX_MOBILES_PER_ENB; ++n) { - if (RC.mac[mod_id]->UE_info.active[n] == TRUE) { + if (RC.mac[mod_id]->UE_info.active[n] == true) { if (i == 0) return n; @@ -580,7 +580,7 @@ uint8_t flexran_get_n_SB(mid_t mod_id, uint8_t cc_id) { Protocol__FlexQam flexran_get_enable64QAM(mid_t mod_id, uint8_t cc_id) { if (!phy_is_present(mod_id, cc_id)) return 0; - if (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM == TRUE) + if (RC.eNB[mod_id][cc_id]->frame_parms.pusch_config_common.enable64QAM == true) return PROTOCOL__FLEX_QAM__FLEQ_MOD_64QAM; else return PROTOCOL__FLEX_QAM__FLEQ_MOD_16QAM; @@ -3585,7 +3585,7 @@ int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__Fl int CC_id, BOOLEAN_t brOption, RrcConfigurationReq *configuration); - carrier->sizeof_SIB1 = do_SIB1(carrier, mod_id, CC_id, FALSE, conf); + carrier->sizeof_SIB1 = do_SIB1(carrier, mod_id, CC_id, false, conf); if (carrier->sizeof_SIB1 < 0) return -1337; /* SIB1 encoding failed, hell will probably break loose */ diff --git a/openair2/F1AP/dummy_enb.c b/openair2/F1AP/dummy_enb.c index 9085fdb57cd772eb39319199540f2a22817a94da..22627c8d926fecbceafe866a7a4bab61d9a291ac 100644 --- a/openair2/F1AP/dummy_enb.c +++ b/openair2/F1AP/dummy_enb.c @@ -32,18 +32,22 @@ void apply_macrlc_config(gNB_RRC_INST *rrc, abort(); } -boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p, - const srb_flag_t srb_flag, - const rb_id_t rb_id, - const mui_t mui, - const confirm_t confirm, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t pt_mode, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi, - const int pdusession_id) { +bool sdap_data_req(protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi, + const int pdusession_id) { abort(); } + +int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) { + abort(); +} diff --git a/openair2/F1AP/f1ap_common.c b/openair2/F1AP/f1ap_common.c index 338b5f0c2b89e577c8651213a4681f1f5bf2f534..efcb1d161bebfb041b42ef8116d03e4d1aceabe3 100644 --- a/openair2/F1AP/f1ap_common.c +++ b/openair2/F1AP/f1ap_common.c @@ -35,27 +35,6 @@ static f1ap_cudu_inst_t *f1_du_inst[NUMBER_OF_eNB_MAX]= {0}; static f1ap_cudu_inst_t *f1_cu_inst[NUMBER_OF_eNB_MAX]= {0}; -#if defined(EMIT_ASN_DEBUG_EXTERN) -int asn_debug = 0; -int asn1_xer_print = 0; - -inline void ASN_DEBUG(const char *fmt, ...) { - if (asn_debug) { - int adi = asn_debug_indent; - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "[ASN1]"); - - while(adi--) - fprintf(stderr, " "); - - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - } -} -#endif - uint8_t F1AP_get_next_transaction_identifier(instance_t enb_mod_idP, instance_t cu_mod_idP) { static uint8_t transaction_identifier[NUMBER_OF_eNB_MAX]; transaction_identifier[enb_mod_idP+cu_mod_idP] = diff --git a/openair2/F1AP/f1ap_common.h b/openair2/F1AP/f1ap_common.h index 66451530a61194479ac98e5f23fb17e78c5cdb60..e89e8a70cce275684d55f8f05c3f18ed41c196d5 100644 --- a/openair2/F1AP/f1ap_common.h +++ b/openair2/F1AP/f1ap_common.h @@ -29,11 +29,6 @@ * \note * \warning */ - -#if HAVE_CONFIG_H_ - #include "config.h" -#endif - #ifndef F1AP_COMMON_H_ #define F1AP_COMMON_H_ @@ -43,10 +38,6 @@ #define F1AP_UE_IDENTIFIER_NUMBER 3 #define F1AP_TRANSACTION_IDENTIFIER_NUMBER 3 -#if defined(EMIT_ASN_DEBUG_EXTERN) - inline void ASN_DEBUG(const char *fmt, ...); -#endif - #include "F1AP_RAT-FrequencyPriorityInformation.h" #include "F1AP_DLUPTNLInformation-ToBeSetup-Item.h" #include "F1AP_PrivateMessage.h" @@ -363,13 +354,6 @@ # error "You are compiling f1ap with the wrong version of ASN1C" #endif -#ifndef FALSE - #define FALSE (0) -#endif -#ifndef TRUE - #define TRUE (!FALSE) -#endif - #define F1AP_UE_ID_FMT "0x%06"PRIX32 #include "assertions.h" diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 62a62095b16fcd22f70632be95d298bc0cdf901a..3ae30cafb9f0c4b164c540811774ab247bca2021 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -79,56 +79,60 @@ int CU_handle_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instance, F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, F1AP_ProtocolIE_ID_id_C_RNTI, true); rnti = ie->value.choice.C_RNTI; - /* RRC Container */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, + F1AP_InitialULRRCMessageTransferIEs_t *rrccont; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, rrccont, container, F1AP_ProtocolIE_ID_id_RRCContainer, true); - AssertFatal(ie!=NULL,"RRCContainer is missing\n"); - - // create an ITTI message and copy SDU - if (f1ap_req(true, instance)->cell_type==CELL_MACRO_GNB) { - message_p = itti_alloc_new_message (TASK_CU_F1, 0, NR_RRC_MAC_CCCH_DATA_IND); - memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - ccch_sdu_len = ie->value.choice.RRCContainer.size; - memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf, - ccch_sdu_len); - } else { - message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_MAC_CCCH_DATA_IND); - memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - ccch_sdu_len = ie->value.choice.RRCContainer.size; - memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, ie->value.choice.RRCContainer.buf, - ccch_sdu_len); - } + AssertFatal(rrccont!=NULL,"RRCContainer is missing\n"); - LOG_I(F1AP, "%s() RRCContainer (CCCH) size %ld: ", __func__, ie->value.choice.RRCContainer.size); - /* DUtoCURRCContainer */ - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, ie, container, + F1AP_InitialULRRCMessageTransferIEs_t *du2cu; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_InitialULRRCMessageTransferIEs_t, du2cu, container, F1AP_ProtocolIE_ID_id_DUtoCURRCContainer, false); - if (ie) { - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t)); - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = ie->value.choice.DUtoCURRCContainer.size; - NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf = malloc(ie->value.choice.DUtoCURRCContainer.size); - memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf, - ie->value.choice.DUtoCURRCContainer.buf, - ie->value.choice.DUtoCURRCContainer.size); - } - int f1ap_uid = f1ap_add_ue(CUtype, instance, rnti); if (f1ap_uid < 0 ) { LOG_E(F1AP, "Failed to add UE \n"); - itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p); return -1; } + // create an ITTI message and copy SDU + if (f1ap_req(true, instance)->cell_type==CELL_MACRO_GNB) { + message_p = itti_alloc_new_message (TASK_CU_F1, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + f1ap_initial_ul_rrc_message_t *ul_rrc = &F1AP_INITIAL_UL_RRC_MESSAGE(message_p); + ul_rrc->nr_cellid = nr_cellid; // CU instance + ul_rrc->crnti = rnti; + ul_rrc->rrc_container_length = rrccont->value.choice.RRCContainer.size; + ul_rrc->rrc_container = malloc(ul_rrc->rrc_container_length); + memcpy(ul_rrc->rrc_container, rrccont->value.choice.RRCContainer.buf, ul_rrc->rrc_container_length); + AssertFatal(du2cu != NULL, "no masterCellGroup in initial UL RRC message\n"); + ul_rrc->du2cu_rrc_container_length = du2cu->value.choice.DUtoCURRCContainer.size; + ul_rrc->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); + memcpy(ul_rrc->du2cu_rrc_container, du2cu->value.choice.DUtoCURRCContainer.buf, ul_rrc->du2cu_rrc_container_length); + itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); + } else { + message_p = itti_alloc_new_message (TASK_CU_F1, 0, RRC_MAC_CCCH_DATA_IND); + memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); + ccch_sdu_len = rrccont->value.choice.RRCContainer.size; + memcpy(RRC_MAC_CCCH_DATA_IND (message_p).sdu, rrccont->value.choice.RRCContainer.buf, + ccch_sdu_len); + NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0; + NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0; + NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len; + NR_RRC_MAC_CCCH_DATA_IND (message_p).nr_cellid = nr_cellid; // CU instance + NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; + NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id; + if (du2cu) { + NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container = malloc(sizeof(OCTET_STRING_t)); + NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->size = du2cu->value.choice.DUtoCURRCContainer.size; + NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf = malloc(du2cu->value.choice.DUtoCURRCContainer.size); + memcpy(NR_RRC_MAC_CCCH_DATA_IND (message_p).du_to_cu_rrc_container->buf, + du2cu->value.choice.DUtoCURRCContainer.buf, + du2cu->value.choice.DUtoCURRCContainer.size); + } + itti_send_msg_to_task (TASK_RRC_ENB, instance, message_p); + } + //getCxt(true,ITTI_MSG_DESTINATION_ID(message_p))->f1ap_ue[f1ap_uid].du_ue_f1ap_id = du_ue_f1ap_id; - NR_RRC_MAC_CCCH_DATA_IND (message_p).frame = 0; - NR_RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = 0; - NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = ccch_sdu_len; - NR_RRC_MAC_CCCH_DATA_IND (message_p).nr_cellid = nr_cellid; // CU instance - NR_RRC_MAC_CCCH_DATA_IND (message_p).rnti = rnti; - NR_RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id; - itti_send_msg_to_task (f1ap_req(true,ITTI_MSG_DESTINATION_ID(message_p))->cell_type==CELL_MACRO_GNB?TASK_RRC_GNB:TASK_RRC_ENB, instance, message_p); return 0; } diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index b3c7363ca4ac0391e7f5b4f9b52eb96162ff863d..b521d0c83dc77ce8fc00652095366bf82f0aeaab 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -172,6 +172,7 @@ void *F1AP_CU_task(void *arg) { LOG_I(F1AP, "CU Task Received F1AP_DL_RRC_MESSAGE\n"); CU_send_DL_RRC_MESSAGE_TRANSFER(ITTI_MSG_DESTINATION_INSTANCE(received_msg), &F1AP_DL_RRC_MESSAGE(received_msg)); + free(F1AP_DL_RRC_MESSAGE(received_msg).rrc_container); break; case F1AP_UE_CONTEXT_SETUP_REQ: // from rrc @@ -180,6 +181,12 @@ void *F1AP_CU_task(void *arg) { &F1AP_UE_CONTEXT_SETUP_REQ(received_msg)); break; + case F1AP_UE_CONTEXT_MODIFICATION_REQ: + LOG_I(F1AP, "CU Task received F1AP_UE_CONTEXT_MODIFICATION_REQ\n"); + CU_send_UE_CONTEXT_MODIFICATION_REQUEST(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg)); + break; + case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc LOG_I(F1AP, "CU Task Received F1AP_UE_CONTEXT_RELEASE_CMD\n"); CU_send_UE_CONTEXT_RELEASE_COMMAND(ITTI_MSG_DESTINATION_INSTANCE(received_msg), diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index c68bfb3852f1119e445a47197c2452f666625be4..cf8d4ce260cf262ef9c9428a080d76191405a177 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -131,21 +131,30 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, ie6->criticality = F1AP_Criticality_reject; ie6->value.present = F1AP_UEContextSetupRequestIEs__value_PR_CUtoDURRCInformation; - /* optional */ - /* 6.1 cG_ConfigInfo */ - if (0) { - const char cG_ConfigInfoStr[]="asdsa1d32sa1d31asd31as"; - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.cG_ConfigInfo, cG_ConfigInfo); - OCTET_STRING_fromBuf(cG_ConfigInfo, cG_ConfigInfoStr, strlen( cG_ConfigInfoStr )) ; + if (f1ap_ue_context_setup_req->cu_to_du_rrc_information!=NULL) { + /* optional */ + /* 6.1 cG_ConfigInfo */ + if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.cG_ConfigInfo, cG_ConfigInfo); + OCTET_STRING_fromBuf(cG_ConfigInfo, (const char *)f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo, + f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo_length); + } /* optional */ /* 6.2 uE_CapabilityRAT_ContainerList */ - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, uE_CapabilityRAT_ContainerList ); - OCTET_STRING_fromBuf(uE_CapabilityRAT_ContainerList, cG_ConfigInfoStr, strlen( cG_ConfigInfoStr )) ; + if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, uE_CapabilityRAT_ContainerList ); + OCTET_STRING_fromBuf(uE_CapabilityRAT_ContainerList, (const char *)f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, + f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); + } /* optional */ /* 6.3 measConfig */ - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.measConfig, measConfig); - OCTET_STRING_fromBuf(measConfig, cG_ConfigInfoStr, strlen( cG_ConfigInfoStr )) ; + if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.measConfig, measConfig); + OCTET_STRING_fromBuf(measConfig, (const char*)f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig, + f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig_length); + } } + /* mandatory */ /* c7. Candidate_SpCell_List */ @@ -238,199 +247,96 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* mandatory */ /* c11. SRBs_ToBeSetup_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie11); - ie11->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_List; - ie11->criticality = F1AP_Criticality_reject; // ? - ie11->value.present = F1AP_UEContextSetupRequestIEs__value_PR_SRBs_ToBeSetup_List; - - for (int i=0; i<f1ap_ue_context_setup_req->srbs_to_be_setup_length; i++) { - // - asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetup_List.list, F1AP_SRBs_ToBeSetup_ItemIEs_t, srbs_toBeSetup_item_ies); - srbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item; // 73 - srbs_toBeSetup_item_ies->criticality = F1AP_Criticality_ignore; - srbs_toBeSetup_item_ies->value.present = F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item; - /* 11.1 SRBs_ToBeSetup_Item */ - F1AP_SRBs_ToBeSetup_Item_t *srbs_toBeSetup_item=&srbs_toBeSetup_item_ies->value.choice.SRBs_ToBeSetup_Item; - /* 11.1.1 sRBID */ - srbs_toBeSetup_item->sRBID = f1ap_ue_context_setup_req->srbs_to_be_setup[i].srb_id; - /* OPTIONAL */ - /* 11.1.2 duplicationIndication */ - //if (0) { - asn1cCallocOne(srbs_toBeSetup_item->duplicationIndication, + if(f1ap_ue_context_setup_req->srbs_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie11); + ie11->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_List; + ie11->criticality = F1AP_Criticality_reject; // ? + ie11->value.present = F1AP_UEContextSetupRequestIEs__value_PR_SRBs_ToBeSetup_List; + + for (int i=0; i<f1ap_ue_context_setup_req->srbs_to_be_setup_length; i++) { + asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetup_List.list, F1AP_SRBs_ToBeSetup_ItemIEs_t, srbs_toBeSetup_item_ies); + srbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item; // 73 + srbs_toBeSetup_item_ies->criticality = F1AP_Criticality_ignore; + srbs_toBeSetup_item_ies->value.present = F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item; + /* 11.1 SRBs_ToBeSetup_Item */ + F1AP_SRBs_ToBeSetup_Item_t *srbs_toBeSetup_item=&srbs_toBeSetup_item_ies->value.choice.SRBs_ToBeSetup_Item; + /* 11.1.1 sRBID */ + srbs_toBeSetup_item->sRBID = f1ap_ue_context_setup_req->srbs_to_be_setup[i].srb_id; + /* OPTIONAL */ + /* 11.1.2 duplicationIndication */ + asn1cCallocOne(srbs_toBeSetup_item->duplicationIndication, F1AP_DuplicationIndication_true); // enum - //} + } } /* mandatory */ /* c12. DRBs_ToBeSetup_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie12); - ie12->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List; - ie12->criticality = F1AP_Criticality_reject; - ie12->value.present = F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List; - LOG_I(F1AP, "Length of drbs_to_be_setup: %d \n", f1ap_ue_context_setup_req->drbs_to_be_setup_length); - - for (int i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; i++) { - // - asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetup_List.list, F1AP_DRBs_ToBeSetup_ItemIEs_t, drbs_toBeSetup_item_ies); - drbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item; - drbs_toBeSetup_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeSetup_item_ies->value.present = F1AP_DRBs_ToBeSetup_ItemIEs__value_PR_DRBs_ToBeSetup_Item; - /* 12.1 DRBs_ToBeSetup_Item */ - F1AP_DRBs_ToBeSetup_Item_t *drbs_toBeSetup_item=&drbs_toBeSetup_item_ies->value.choice.DRBs_ToBeSetup_Item; - /* 12.1.1 dRBID */ - drbs_toBeSetup_item->dRBID = f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id; // 9 - /* 12.1.2 qoSInformation */ - int some_decide_qos = 0; // BK: Need Check - - if (some_decide_qos) { - drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; - /* 12.1.2.1 eUTRANQoS */ - asn1cCalloc(drbs_toBeSetup_item->qoSInformation.choice.eUTRANQoS, eUTRANQoS); - /* 12.1.2.1.1 qCI */ - eUTRANQoS->qCI = 254L; - /* 12.1.2.1.2 allocationAndRetentionPriority */ - { - /* 12.1.2.1.2.1 priorityLevel */ - eUTRANQoS->allocationAndRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum - /* 12.1.2.1.2.2 pre_emptionCapability */ - eUTRANQoS->allocationAndRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_may_trigger_pre_emption; // enum - /* 12.1.2.1.2.2 pre_emptionVulnerability */ - eUTRANQoS->allocationAndRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum - } - - /* OPTIONAL */ - /* 12.1.2.1.3 gbrQosInformation */ - if (0) { - eUTRANQoS->gbrQosInformation = (F1AP_GBR_QosInformation_t *)calloc(1, sizeof(F1AP_GBR_QosInformation_t)); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateDL, 1L); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateUL, 1L); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateDL, 1L); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateUL, 1L); - } - } else { - /* 12.1.2 DRB_Information */ - drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_choice_extension; - F1AP_QoSInformation_ExtIEs_t *ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(*ie)); - ie->id = F1AP_ProtocolIE_ID_id_DRB_Information; - ie->criticality = F1AP_Criticality_reject; - ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information; - F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information; - drbs_toBeSetup_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie; - /* 12.1.2.1 dRB_QoS */ - { - /* qoS_Characteristics */ - { - int some_decide_qoS_characteristics = 0; // BK: Need Check - - if (some_decide_qoS_characteristics) { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - setQos(DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI); - } else { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI, tmp); - /* qoSPriorityLevel */ - tmp->qoSPriorityLevel = 1L; - /* packetDelayBudget */ - tmp->packetDelayBudget = 1L; - /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = 1L; - tmp->packetErrorRate.pER_Exponent = 6L; - - /* OPTIONAL */ - /* delayCritical */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); - } - - /* OPTIONAL */ - /* averagingWindow */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); - } - - /* OPTIONAL */ - /* maxDataBurstVolume */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); - } - } // if some_decide_qoS_characteristics - } // qoS_Characteristics - /* nGRANallocationRetentionPriority */ + if(f1ap_ue_context_setup_req->drbs_to_be_setup_length){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie12); + ie12->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List; + ie12->criticality = F1AP_Criticality_reject; + ie12->value.present = F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List; + LOG_I(F1AP, "Length of drbs_to_be_setup: %d \n", f1ap_ue_context_setup_req->drbs_to_be_setup_length); + + for (int i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; i++) { + // + asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetup_List.list, F1AP_DRBs_ToBeSetup_ItemIEs_t, drbs_toBeSetup_item_ies); + drbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item; + drbs_toBeSetup_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeSetup_item_ies->value.present = F1AP_DRBs_ToBeSetup_ItemIEs__value_PR_DRBs_ToBeSetup_Item; + /* 12.1 DRBs_ToBeSetup_Item */ + F1AP_DRBs_ToBeSetup_Item_t *drbs_toBeSetup_item=&drbs_toBeSetup_item_ies->value.choice.DRBs_ToBeSetup_Item; + /* 12.1.1 dRBID */ + drbs_toBeSetup_item->dRBID = f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id; // 9 + /* 12.1.2 qoSInformation */ + int some_decide_qos = 0; // BK: Need Check + + if (some_decide_qos) { + drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; + /* 12.1.2.1 eUTRANQoS */ + asn1cCalloc(drbs_toBeSetup_item->qoSInformation.choice.eUTRANQoS, eUTRANQoS); + /* 12.1.2.1.1 qCI */ + eUTRANQoS->qCI = 254L; + /* 12.1.2.1.2 allocationAndRetentionPriority */ { - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information, tmp); - asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); - - /* OPTIONAL */ - /* maxPacketLossRateDownlink */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - } - - /* OPTIONAL */ - /* maxPacketLossRateUplink */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } + /* 12.1.2.1.2.1 priorityLevel */ + eUTRANQoS->allocationAndRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + /* 12.1.2.1.2.2 pre_emptionCapability */ + eUTRANQoS->allocationAndRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_may_trigger_pre_emption; // enum + /* 12.1.2.1.2.2 pre_emptionVulnerability */ + eUTRANQoS->allocationAndRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum } /* OPTIONAL */ - /* reflective_QoS_Attribute */ + /* 12.1.2.1.3 gbrQosInformation */ if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); + eUTRANQoS->gbrQosInformation = (F1AP_GBR_QosInformation_t *)calloc(1, sizeof(F1AP_GBR_QosInformation_t)); + asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateDL, 1L); + asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateUL, 1L); + asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateDL, 1L); + asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateUL, 1L); } - } // dRB_QoS - /* 12.1.2.2 sNSSAI */ - { - /* sST */ - OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, "1", 1); - - /* OPTIONAL */ - /* sD */ - if (0) { - asn1cCalloc(DRB_Information->sNSSAI.sD, tmp); - OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); - } - } - - /* OPTIONAL */ - /* 12.1.2.3 notificationControl */ - if (0) { - asn1cCallocOne(DRB_Information->notificationControl, - F1AP_NotificationControl_active); // enum - } - - /* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy - - for (int k = 0; k < 1; k ++) { - asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list, - F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item); - /* qoSFlowIndicator */ - flows_mapped_to_drb_item->qoSFlowIdentifier = 1L; - /* qoSFlowLevelQoSParameters */ + } else { + /* 12.1.2 DRB_Information */ + drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_choice_extension; + F1AP_QoSInformation_ExtIEs_t *ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(*ie)); + ie->id = F1AP_ProtocolIE_ID_id_DRB_Information; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information; + F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information; + drbs_toBeSetup_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie; + /* 12.1.2.1 dRB_QoS */ { /* qoS_Characteristics */ { int some_decide_qoS_characteristics = 0; // BK: Need Check - F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics; if (some_decide_qoS_characteristics) { - QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - setQos(QosParams->choice.non_Dynamic_5QI); + DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + setQos(DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI); } else { - QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); + DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI, tmp); /* qoSPriorityLevel */ tmp->qoSPriorityLevel = 1L; /* packetDelayBudget */ @@ -442,36 +348,33 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* OPTIONAL */ /* delayCritical */ if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp); - *tmp = 1L; + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); } /* OPTIONAL */ /* averagingWindow */ if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp); - *tmp = 1L; + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); } /* OPTIONAL */ /* maxDataBurstVolume */ if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp); - *tmp= 1L; + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); } } // if some_decide_qoS_characteristics } // qoS_Characteristics /* nGRANallocationRetentionPriority */ { - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum } // nGRANallocationRetentionPriority /* OPTIONAL */ /* gBR_QoS_Flow_Information */ if (0) { - asn1cCalloc(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp); + asn1cCalloc(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information, tmp); asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); @@ -480,80 +383,186 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* OPTIONAL */ /* maxPacketLossRateDownlink */ if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); + asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); } /* OPTIONAL */ /* maxPacketLossRateUplink */ if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); + asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); } } /* OPTIONAL */ /* reflective_QoS_Attribute */ if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); + asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); } - } // qoSFlowLevelQoSParameters - } - } // if some_decide_qos - - /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ - for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { - /* Here the callback function used as input is not the right one. Need to create a new one probably for F1-U, not sure - * if the kind of input parameters to the callback function are convenient though for gtp-u over F1-U.*/ - //Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU - transport_layer_addr_t addr; - int sz=sizeof(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address); - memcpy(addr.buffer,&f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz); - addr.length = sz*8; - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid= - newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst, - f1ap_ue_context_setup_req->rnti, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, - 0xFFFF, // We will set the right value from DU answer - addr, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port, - cu_f1u_data_req); - /* 12.3.1 ULTunnels_ToBeSetup_Item */ - asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list, - F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); - uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc( uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, - gTPTunnel); - /* 12.3.1.1.1 transportLayerAddress */ - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].tl_address, + } // dRB_QoS + /* 12.1.2.2 sNSSAI */ + { + /* sST */ + OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, "1", 1); + + /* OPTIONAL */ + /* sD */ + if (0) { + asn1cCalloc(DRB_Information->sNSSAI.sD, tmp); + OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + } + } + + /* OPTIONAL */ + /* 12.1.2.3 notificationControl */ + if (0) { + asn1cCallocOne(DRB_Information->notificationControl, + F1AP_NotificationControl_active); // enum + } + + /* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy + + for (int k = 0; k < 1; k ++) { + asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list, + F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item); + /* qoSFlowIndicator */ + flows_mapped_to_drb_item->qoSFlowIdentifier = 1L; + /* qoSFlowLevelQoSParameters */ + { + /* qoS_Characteristics */ + { + int some_decide_qoS_characteristics = 0; // BK: Need Check + F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics; + + if (some_decide_qoS_characteristics) { + QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + setQos(QosParams->choice.non_Dynamic_5QI); + } else { + QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); + /* qoSPriorityLevel */ + tmp->qoSPriorityLevel = 1L; + /* packetDelayBudget */ + tmp->packetDelayBudget = 1L; + /* packetErrorRate */ + tmp->packetErrorRate.pER_Scalar = 1L; + tmp->packetErrorRate.pER_Exponent = 6L; + + /* OPTIONAL */ + /* delayCritical */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp); + *tmp = 1L; + } + + /* OPTIONAL */ + /* averagingWindow */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp); + *tmp = 1L; + } + + /* OPTIONAL */ + /* maxDataBurstVolume */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp); + *tmp= 1L; + } + } // if some_decide_qoS_characteristics + } // qoS_Characteristics + /* nGRANallocationRetentionPriority */ + { + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum + } // nGRANallocationRetentionPriority + + /* OPTIONAL */ + /* gBR_QoS_Flow_Information */ + if (0) { + asn1cCalloc(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp); + asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); + + /* OPTIONAL */ + /* maxPacketLossRateDownlink */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); + } + + /* OPTIONAL */ + /* maxPacketLossRateUplink */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); + } + } + + /* OPTIONAL */ + /* reflective_QoS_Attribute */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); + } + } // qoSFlowLevelQoSParameters + } + } // if some_decide_qos + + /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ + for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { + /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/ + transport_layer_addr_t addr; + int sz=sizeof(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address); + memcpy(addr.buffer,&f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz); + addr.length = sz*8; + f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst, + f1ap_ue_context_setup_req->rnti, + f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, + f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, + 0xFFFF, // We will set the right value from DU answer + -1, // no qfi + addr, + f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port, + cu_f1u_data_req, + NULL); + /* 12.3.1 ULTunnels_ToBeSetup_Item */ + asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list, + F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + asn1cCalloc( uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, + gTPTunnel); + /* 12.3.1.1.1 transportLayerAddress */ + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].tl_address, &gTPTunnel->transportLayerAddress); - /* 12.3.1.1.2 gTP_TEID */ - INT32_TO_OCTET_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid, - &gTPTunnel->gTP_TEID); - } + /* 12.3.1.1.2 gTP_TEID */ + INT32_TO_OCTET_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid, + &gTPTunnel->gTP_TEID); + } - /* 12.1.4 rLCMode */ - /* TODO use rlc_mode from f1ap_drb_to_be_setup */ - switch (f1ap_ue_context_setup_req->drbs_to_be_setup[i].rlc_mode) { - case RLC_MODE_AM: - drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_am; - break; + /* 12.1.4 rLCMode */ + /* TODO use rlc_mode from f1ap_drb_to_be_setup */ + switch (f1ap_ue_context_setup_req->drbs_to_be_setup[i].rlc_mode) { + case RLC_MODE_AM: + drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_am; + break; - default: - drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; - } + default: + drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; + } - /* OPTIONAL */ - /* 12.1.5 ULConfiguration */ - if (0) { - asn1cCalloc(drbs_toBeSetup_item->uLConfiguration, tmp); - tmp->uLUEConfiguration = F1AP_ULUEConfiguration_no_data; - } + /* OPTIONAL */ + /* 12.1.5 ULConfiguration */ + if (0) { + asn1cCalloc(drbs_toBeSetup_item->uLConfiguration, tmp); + tmp->uLUEConfiguration = F1AP_ULUEConfiguration_no_data; + } - /* OPTIONAL */ - /* 12.1.6 duplicationActivation */ - if (0) { - asn1cCalloc(drbs_toBeSetup_item->duplicationActivation, tmp); - *tmp = F1AP_DuplicationActivation_active; // enum + /* OPTIONAL */ + /* 12.1.6 duplicationActivation */ + if (0) { + asn1cCalloc(drbs_toBeSetup_item->duplicationActivation, tmp); + *tmp = F1AP_DuplicationActivation_active; // enum + } } } @@ -662,9 +671,10 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, return -1; } - f1ap_ue_context_setup_resp->du_to_cu_rrc_information = (uint8_t *)calloc(1,ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); - memcpy(f1ap_ue_context_setup_resp->du_to_cu_rrc_information, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.buf, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); - f1ap_ue_context_setup_resp->du_to_cu_rrc_information_length = ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size; + f1ap_ue_context_setup_resp->du_to_cu_rrc_information = (du_to_cu_rrc_information_t *)calloc(1,sizeof(du_to_cu_rrc_information_t)); + f1ap_ue_context_setup_resp->du_to_cu_rrc_information->cellGroupConfig = (uint8_t *)calloc(1,ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); + memcpy(f1ap_ue_context_setup_resp->du_to_cu_rrc_information->cellGroupConfig, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.buf, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); + f1ap_ue_context_setup_resp->du_to_cu_rrc_information->cellGroupConfig_length = ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size; // DRBs_Setup_List F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupResponseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_DRBs_Setup_List, false); @@ -896,12 +906,14 @@ int CU_send_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, /* optional */ /* c4. RRCContainer */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer; - ie4->criticality = F1AP_Criticality_ignore; - ie4->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_RRCContainer; - OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)cmd->rrc_container, + if(cmd->rrc_container!=NULL){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCommandIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie4->criticality = F1AP_Criticality_ignore; + ie4->value.present = F1AP_UEContextReleaseCommandIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie4->value.choice.RRCContainer, (const char *)cmd->rrc_container, cmd->rrc_container_length); + } /* encode */ if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { @@ -961,9 +973,6 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, LOG_E(F1AP, "could not find ue_context of UE RNTI %x\n", rnti); } -#ifdef ITTI_SIM - return 0; -#endif } else { struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[instance], rnti); @@ -1008,7 +1017,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, return 0; } //void CU_send_UE_CONTEXT_MODIFICATION_REQUEST(F1AP_UEContextModificationRequest_t *UEContextModificationRequest) { -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context_setup_t *f1ap_ue_context_modification_req) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationRequest_t *out; uint8_t *buffer=NULL; @@ -1029,14 +1038,14 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = 126L; + ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_get_cu_ue_f1ap_id(CUtype, instance, f1ap_ue_context_modification_req->rnti);; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = 651L; + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(CUtype, instance, f1ap_ue_context_modification_req->rnti);; /* optional */ /* c3. NRCGI */ @@ -1049,13 +1058,15 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { addnRCGI(ie3->value.choice.NRCGI, &hardCoded); } - /* mandatory */ + /* optional */ /* c4. ServCellIndex */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_ServCellIndex; - ie4->criticality = F1AP_Criticality_reject; - ie4->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ServCellIndex; - ie4->value.choice.ServCellIndex = 5L; + if(0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie4); + ie4->id = F1AP_ProtocolIE_ID_id_ServCellIndex; + ie4->criticality = F1AP_Criticality_reject; + ie4->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ServCellIndex; + ie4->value.choice.ServCellIndex = 5L; + } /* optional */ /* c5. DRXCycle */ @@ -1077,47 +1088,58 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { } /* optional */ - /* c5. CUtoDURRCInformation */ - if (1) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie5); - ie5->id = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation; - ie5->criticality = F1AP_Criticality_reject; - ie5->value.present = F1AP_UEContextModificationRequestIEs__value_PR_CUtoDURRCInformation; - asn1cCalloc(ie5->value.choice.CUtoDURRCInformation.cG_ConfigInfo, tmp); + /* c6. CUtoDURRCInformation */ + if (f1ap_ue_context_modification_req->cu_to_du_rrc_information!=NULL) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie6); + ie6->id = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation; + ie6->criticality = F1AP_Criticality_reject; + ie6->value.present = F1AP_UEContextModificationRequestIEs__value_PR_CUtoDURRCInformation; + /* 6.1 cG_ConfigInfo */ + if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.cG_ConfigInfo, cG_ConfigInfo); + OCTET_STRING_fromBuf(cG_ConfigInfo, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo, + f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo_length); + } /* optional */ - OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); - asn1cCalloc(ie5->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, - tmp2); + /* 6.2 uE_CapabilityRAT_ContainerList */ + if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, uE_CapabilityRAT_ContainerList ); + OCTET_STRING_fromBuf(uE_CapabilityRAT_ContainerList, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, + f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length) ; + } /* optional */ - OCTET_STRING_fromBuf(tmp2, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); + /* 6.3 measConfig */ + if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig!=NULL){ + asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.measConfig, measConfig); + OCTET_STRING_fromBuf(measConfig, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig, + f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig_length); + } } /* optional */ - /* c6. TransmissionActionIndicator */ - if (1) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie6); - ie6->id = F1AP_ProtocolIE_ID_id_TransmissionActionIndicator; - ie6->criticality = F1AP_Criticality_ignore; - ie6->value.present = F1AP_UEContextModificationRequestIEs__value_PR_TransmissionActionIndicator; - ie6->value.choice.TransmissionActionIndicator = F1AP_TransmissionActionIndicator_stop; + /* c7. TransmissionActionIndicator */ + if (0) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie7); + ie7->id = F1AP_ProtocolIE_ID_id_TransmissionActionIndicator; + ie7->criticality = F1AP_Criticality_ignore; + ie7->value.present = F1AP_UEContextModificationRequestIEs__value_PR_TransmissionActionIndicator; + ie7->value.choice.TransmissionActionIndicator = F1AP_TransmissionActionIndicator_stop; } /* optional */ - /* c7. ResourceCoordinationTransferContainer */ + /* c8. ResourceCoordinationTransferContainer */ if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie7); - ie7->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer; - ie7->criticality = F1AP_Criticality_ignore; - ie7->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ResourceCoordinationTransferContainer; - OCTET_STRING_fromBuf(&ie7->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as", + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie8); + ie8->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer; + ie8->criticality = F1AP_Criticality_ignore; + ie8->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ResourceCoordinationTransferContainer; + OCTET_STRING_fromBuf(&ie8->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as", strlen("asdsa1d32sa1d31asd31as")); } /* optional */ /* c7. RRCRconfigurationCompleteIndicator */ - if (1) { + if (f1ap_ue_context_modification_req->ReconfigComplOutcome == RRCreconf_success) { asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie71); ie71->id = F1AP_ProtocolIE_ID_id_RRCReconfigurationCompleteIndicator; ie71->criticality = F1AP_Criticality_ignore; @@ -1127,218 +1149,488 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { /* optional */ /* c8. RRCContainer */ - if (1) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie8); - ie8->id = F1AP_ProtocolIE_ID_id_RRCContainer; - ie8->criticality = F1AP_Criticality_ignore; - ie8->value.present = F1AP_UEContextModificationRequestIEs__value_PR_RRCContainer; - OCTET_STRING_fromBuf(&ie8->value.choice.RRCContainer, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); + if (f1ap_ue_context_modification_req->rrc_container != NULL) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie81); + ie81->id = F1AP_ProtocolIE_ID_id_RRCContainer; + ie81->criticality = F1AP_Criticality_ignore; + ie81->value.present = F1AP_UEContextModificationRequestIEs__value_PR_RRCContainer; + OCTET_STRING_fromBuf(&ie81->value.choice.RRCContainer, (const char*)f1ap_ue_context_modification_req->rrc_container, + f1ap_ue_context_modification_req->rrc_container_length); } - /* mandatory */ + /* optional */ /* c9. SCell_ToBeSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie9); - ie9->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_List; - ie9->criticality = F1AP_Criticality_ignore; - ie9->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeSetupMod_List; + if(0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie9); + ie9->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_List; + ie9->criticality = F1AP_Criticality_ignore; + ie9->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeSetupMod_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie9->value.choice.SCell_ToBeSetupMod_List.list, + for (int i=0; i<1; i++) { + // + asn1cSequenceAdd(ie9->value.choice.SCell_ToBeSetupMod_List.list, F1AP_SCell_ToBeSetupMod_ItemIEs_t, scell_toBeSetupMod_item_ies); - scell_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_Item; - scell_toBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; - scell_toBeSetupMod_item_ies->value.present = F1AP_SCell_ToBeSetupMod_ItemIEs__value_PR_SCell_ToBeSetupMod_Item; - /* 8.1 SCell_ToBeSetup_Item */ - F1AP_SCell_ToBeSetupMod_Item_t *scell_toBeSetupMod_item= - &scell_toBeSetupMod_item_ies->value.choice.SCell_ToBeSetupMod_Item; - // /* - sCell_ID */ - addnRCGI(scell_toBeSetupMod_item->sCell_ID, &hardCoded); - /* sCellIndex */ - scell_toBeSetupMod_item->sCellIndex = 6; // issue here + scell_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_Item; + scell_toBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; + scell_toBeSetupMod_item_ies->value.present = F1AP_SCell_ToBeSetupMod_ItemIEs__value_PR_SCell_ToBeSetupMod_Item; + /* 8.1 SCell_ToBeSetup_Item */ + F1AP_SCell_ToBeSetupMod_Item_t *scell_toBeSetupMod_item= + &scell_toBeSetupMod_item_ies->value.choice.SCell_ToBeSetupMod_Item; + // /* - sCell_ID */ + addnRCGI(scell_toBeSetupMod_item->sCell_ID, &hardCoded); + /* sCellIndex */ + scell_toBeSetupMod_item->sCellIndex = 6; // issue here + } } - /* mandatory */ + /* optional */ /* c10. SCell_ToBeRemoved_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie10); - ie10->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_List; - ie10->criticality = F1AP_Criticality_ignore; - ie10->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeRemoved_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie10->value.choice.SCell_ToBeRemoved_List.list, + if(0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie10); + ie10->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_List; + ie10->criticality = F1AP_Criticality_ignore; + ie10->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeRemoved_List; + + for (int i=0; i<1; i++) { + // + asn1cSequenceAdd(ie10->value.choice.SCell_ToBeRemoved_List.list, F1AP_SCell_ToBeRemoved_ItemIEs_t, scell_toBeRemoved_item_ies); - scell_toBeRemoved_item_ies = (F1AP_SCell_ToBeRemoved_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); - //memset((void *)&scell_toBeRemoved_item_ies, 0, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); - scell_toBeRemoved_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_Item; - scell_toBeRemoved_item_ies->criticality = F1AP_Criticality_ignore; - scell_toBeRemoved_item_ies->value.present = F1AP_SCell_ToBeRemoved_ItemIEs__value_PR_SCell_ToBeRemoved_Item; - /* 10.1 SCell_ToBeRemoved_Item */ - F1AP_SCell_ToBeRemoved_Item_t *scell_toBeRemoved_item= - &scell_toBeRemoved_item_ies->value.choice.SCell_ToBeRemoved_Item; - /* - sCell_ID */ - addnRCGI(scell_toBeRemoved_item->sCell_ID, &hardCoded); + scell_toBeRemoved_item_ies = (F1AP_SCell_ToBeRemoved_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); + //memset((void *)&scell_toBeRemoved_item_ies, 0, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); + scell_toBeRemoved_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_Item; + scell_toBeRemoved_item_ies->criticality = F1AP_Criticality_ignore; + scell_toBeRemoved_item_ies->value.present = F1AP_SCell_ToBeRemoved_ItemIEs__value_PR_SCell_ToBeRemoved_Item; + /* 10.1 SCell_ToBeRemoved_Item */ + F1AP_SCell_ToBeRemoved_Item_t *scell_toBeRemoved_item= + &scell_toBeRemoved_item_ies->value.choice.SCell_ToBeRemoved_Item; + /* - sCell_ID */ + addnRCGI(scell_toBeRemoved_item->sCell_ID, &hardCoded); + } } /* mandatory */ /* c11. SRBs_ToBeSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie11); - ie11->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List; - ie11->criticality = F1AP_Criticality_reject; - ie11->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeSetupMod_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetupMod_List.list, - F1AP_SRBs_ToBeSetupMod_ItemIEs_t, srbs_toBeSetupMod_item_ies); - srbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_Item; - srbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; - srbs_toBeSetupMod_item_ies->value.present = F1AP_SRBs_ToBeSetupMod_ItemIEs__value_PR_SRBs_ToBeSetupMod_Item; - /* 9.1 SRBs_ToBeSetupMod_Item */ - F1AP_SRBs_ToBeSetupMod_Item_t *srbs_toBeSetupMod_item= - &srbs_toBeSetupMod_item_ies->value.choice.SRBs_ToBeSetupMod_Item; - /* - sRBID */ - srbs_toBeSetupMod_item->sRBID = 3L; + if(f1ap_ue_context_modification_req->srbs_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie11); + ie11->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List; + ie11->criticality = F1AP_Criticality_reject; + ie11->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeSetupMod_List; + + for (int i=0; i<f1ap_ue_context_modification_req->srbs_to_be_setup_length; i++) { + // + asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetupMod_List, F1AP_SRBs_ToBeSetupMod_ItemIEs_t, srbs_toBeSetupMod_item_ies); + srbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_Item; // 73 + srbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; + srbs_toBeSetupMod_item_ies->value.present = F1AP_SRBs_ToBeSetupMod_ItemIEs__value_PR_SRBs_ToBeSetupMod_Item; + /* 11.1 SRBs_ToBeSetup_Item */ + F1AP_SRBs_ToBeSetupMod_Item_t *srbs_toBeSetupMod_item=&srbs_toBeSetupMod_item_ies->value.choice.SRBs_ToBeSetupMod_Item; + /* 11.1.1 sRBID */ + srbs_toBeSetupMod_item->sRBID = f1ap_ue_context_modification_req->srbs_to_be_setup[i].srb_id; + /* OPTIONAL */ + /* 11.1.2 duplicationIndication */ + asn1cCallocOne(srbs_toBeSetupMod_item->duplicationIndication, + F1AP_DuplicationIndication_true); // enum + } } /* mandatory */ /* c12. DRBs_ToBeSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie12); - ie12->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List; - ie12->criticality = F1AP_Criticality_reject; - ie12->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List; + if(f1ap_ue_context_modification_req->drbs_to_be_setup_length){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie12); + ie12->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List; + ie12->criticality = F1AP_Criticality_reject; + ie12->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetupMod_List.list, + for (int i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_setup_length; i++) { + asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetupMod_List.list, F1AP_DRBs_ToBeSetupMod_ItemIEs_t, drbs_toBeSetupMod_item_ies); - drbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item; - drbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeSetupMod_item_ies->value.present = F1AP_DRBs_ToBeSetupMod_ItemIEs__value_PR_DRBs_ToBeSetupMod_Item; - /* 12.1 DRBs_ToBeSetupMod_Item */ - F1AP_DRBs_ToBeSetupMod_Item_t *drbs_toBeSetupMod_item= - &drbs_toBeSetupMod_item_ies->value.choice.DRBs_ToBeSetupMod_Item; - /* dRBID */ - drbs_toBeSetupMod_item->dRBID = 30L; - /* qoSInformation */ - drbs_toBeSetupMod_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; - drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); - drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS->qCI = 253L; - /* uLUPTNLInformation_ToBeSetup_List */ - int maxnoofULTunnels = 1; // 2; - - for (int j=0; j<maxnoofULTunnels; j++) { - /* ULTunnels_ToBeSetup_Item */ - asn1cSequenceAdd( drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list, + drbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item; + drbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeSetupMod_item_ies->value.present = F1AP_DRBs_ToBeSetupMod_ItemIEs__value_PR_DRBs_ToBeSetupMod_Item; + /* 12.1 DRBs_ToBeSetupMod_Item */ + F1AP_DRBs_ToBeSetupMod_Item_t *drbs_toBeSetupMod_item= + &drbs_toBeSetupMod_item_ies->value.choice.DRBs_ToBeSetupMod_Item; + /* dRBID */ + drbs_toBeSetupMod_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id; + /* qoSInformation */ + + if(f1ap_ue_context_modification_req->QoS_information_type == EUTRAN_QoS){ + drbs_toBeSetupMod_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; + drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); + drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS->qCI = 253L; + /* uLUPTNLInformation_ToBeSetup_List */ + int maxnoofULTunnels = 1; // 2; + + for (int j=0; j<maxnoofULTunnels; j++) { + /* ULTunnels_ToBeSetup_Item */ + asn1cSequenceAdd( drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list, F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); - uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, gTPTunnel) - /* transportLayerAddress */ - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); - /* gTP_TEID */ - OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "4567", - strlen("4567")); - } + /* transportLayerAddress */ + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); + /* gTP_TEID */ + OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "4567", + strlen("4567")); + } - /* rLCMode */ - drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; // enum + /* rLCMode */ + drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; // enum - /* OPTIONAL */ - /* ULConfiguration */ - if (0) { - drbs_toBeSetupMod_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); + /* OPTIONAL */ + /* ULConfiguration */ + if (0) { + drbs_toBeSetupMod_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); + } + } //QoS information + + else{ + /* 12.1.2 DRB_Information */ + drbs_toBeSetupMod_item->qoSInformation.present = F1AP_QoSInformation_PR_choice_extension; + F1AP_QoSInformation_ExtIEs_t *ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(*ie)); + ie->id = F1AP_ProtocolIE_ID_id_DRB_Information; + ie->criticality = F1AP_Criticality_reject; + ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information; + F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information; + drbs_toBeSetupMod_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie; + /* 12.1.2.1 dRB_QoS */ + { + /* qoS_Characteristics */ + { + int some_decide_qoS_characteristics = 0; // BK: Need Check + + if (some_decide_qoS_characteristics) { + DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + setQos(DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI); + } else { + DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI, tmp); + /* qoSPriorityLevel */ + tmp->qoSPriorityLevel = 1L; + /* packetDelayBudget */ + tmp->packetDelayBudget = 1L; + /* packetErrorRate */ + tmp->packetErrorRate.pER_Scalar = 1L; + tmp->packetErrorRate.pER_Exponent = 6L; + + /* OPTIONAL */ + /* delayCritical */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); + } + + /* OPTIONAL */ + /* averagingWindow */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); + } + + /* OPTIONAL */ + /* maxDataBurstVolume */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); + } + } // if some_decide_qoS_characteristics + + } // qoS_Characteristics + /* nGRANallocationRetentionPriority */ + { + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum + DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum + } // nGRANallocationRetentionPriority + + /* OPTIONAL */ + /* gBR_QoS_Flow_Information */ + if (0) { + asn1cCalloc(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information, tmp); + asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); + + /* OPTIONAL */ + /* maxPacketLossRateDownlink */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); + } + + /* OPTIONAL */ + /* maxPacketLossRateUplink */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); + } + } + + /* OPTIONAL */ + /* reflective_QoS_Attribute */ + if (0) { + asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); + } + } // dRB_QoS + /* 12.1.2.2 sNSSAI */ + { + /* sST */ + + OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, "1", 1); + + /* OPTIONAL */ + /* sD */ + if (0) { + asn1cCalloc(DRB_Information->sNSSAI.sD, tmp); + OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as", + strlen("asdsa1d32sa1d31asd31as")); + } + } + + /* OPTIONAL */ + /* 12.1.2.3 notificationControl */ + if (0) { + asn1cCallocOne(DRB_Information->notificationControl, + F1AP_NotificationControl_active); // enum + } + + /* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy + + for (int k = 0; k < 1; k ++) { + asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list, + F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item); + /* qoSFlowIndicator */ + flows_mapped_to_drb_item->qoSFlowIdentifier = 1L; + /* qoSFlowLevelQoSParameters */ + { + /* qoS_Characteristics */ + { + int some_decide_qoS_characteristics = 0; // BK: Need Check + F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics; + + if (some_decide_qoS_characteristics) { + QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; + setQos(QosParams->choice.non_Dynamic_5QI); + } else { + QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; + asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); + /* qoSPriorityLevel */ + tmp->qoSPriorityLevel = 1L; + /* packetDelayBudget */ + tmp->packetDelayBudget = 1L; + /* packetErrorRate */ + tmp->packetErrorRate.pER_Scalar = 1L; + tmp->packetErrorRate.pER_Exponent = 6L; + + /* OPTIONAL */ + /* delayCritical */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp); + *tmp = 1L; + } + + /* OPTIONAL */ + /* averagingWindow */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp); + *tmp = 1L; + } + + /* OPTIONAL */ + /* maxDataBurstVolume */ + if (0) { + asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp); + *tmp= 1L; + } + } // if some_decide_qoS_characteristics + + } // qoS_Characteristics + /* nGRANallocationRetentionPriority */ + { + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum + flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum + } // nGRANallocationRetentionPriority + + /* OPTIONAL */ + /* gBR_QoS_Flow_Information */ + if (0) { + asn1cCalloc(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp); + asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); + asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); + + /* OPTIONAL */ + /* maxPacketLossRateDownlink */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); + } + + /* OPTIONAL */ + /* maxPacketLossRateUplink */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); + } + } + + /* OPTIONAL */ + /* reflective_QoS_Attribute */ + if (0) { + asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); + } + } // qoSFlowLevelQoSParameters + } + + } //QoS information + + /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ + for (int j = 0; j < f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { + /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/ + transport_layer_addr_t addr; + int sz=sizeof(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address); + memcpy(addr.buffer,&f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz); + addr.length = sz*8; + + f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst, + f1ap_ue_context_modification_req->rnti, + f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id, + f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id, + 0xFFFF, // We will set the right value from DU answer + -1, // no qfi + addr, + f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].port, + cu_f1u_data_req, + NULL); + /* 12.3.1 ULTunnels_ToBeSetup_Item */ + asn1cSequenceAdd(drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list, + F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + asn1cCalloc( uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, + gTPTunnel); + /* 12.3.1.1.1 transportLayerAddress */ + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].tl_address, + &gTPTunnel->transportLayerAddress); + /* 12.3.1.1.2 gTP_TEID */ + INT32_TO_OCTET_STRING(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid, + &gTPTunnel->gTP_TEID); + } + /* 12.1.4 rLCMode */ + /* TODO use rlc_mode from f1ap_drb_to_be_setup */ + switch (f1ap_ue_context_modification_req->drbs_to_be_setup[i].rlc_mode) { + case RLC_MODE_AM: + drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_am; + break; + + default: + drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; + } + + /* OPTIONAL */ + /* 12.1.5 ULConfiguration */ + if (0) { + asn1cCalloc(drbs_toBeSetupMod_item->uLConfiguration, tmp); + tmp->uLUEConfiguration = F1AP_ULUEConfiguration_no_data; + } + + /* OPTIONAL */ + /* 12.1.6 duplicationActivation */ + if (0) { + asn1cCalloc(drbs_toBeSetupMod_item->duplicationActivation, tmp); + *tmp = F1AP_DuplicationActivation_active; // enum + } } } - /* mandatory */ - /* c13. DRBs_ToBeModified_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie13); - ie13->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_List; - ie13->criticality = F1AP_Criticality_reject; - ie13->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeModified_List; + /* optional */ + if(0){ + /* c13. DRBs_ToBeModified_List */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie13); + ie13->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_List; + ie13->criticality = F1AP_Criticality_reject; + ie13->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeModified_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd( ie13->value.choice.DRBs_ToBeModified_List.list, + for (int i=0; i<1; i++) { + // + asn1cSequenceAdd( ie13->value.choice.DRBs_ToBeModified_List.list, F1AP_DRBs_ToBeModified_ItemIEs_t, drbs_toBeModified_item_ies); - drbs_toBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_Item; - drbs_toBeModified_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeModified_item_ies->value.present = F1AP_DRBs_ToBeModified_ItemIEs__value_PR_DRBs_ToBeModified_Item; - /* 13.1 SRBs_ToBeModified_Item */ - F1AP_DRBs_ToBeModified_Item_t *drbs_toBeModified_item= - &drbs_toBeModified_item_ies->value.choice.DRBs_ToBeModified_Item; - /* dRBID */ - drbs_toBeModified_item->dRBID = 30L; - /* qoSInformation */ - asn1cCalloc(drbs_toBeModified_item->qoSInformation, tmp); - tmp->present = F1AP_QoSInformation_PR_eUTRANQoS; - tmp->choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); - tmp->choice.eUTRANQoS->qCI = 254L; - /* ULTunnels_ToBeModified_List */ - int maxnoofULTunnels = 1; // 2; - - for (int j=0; j<maxnoofULTunnels; j++) { - /* ULTunnels_ToBeModified_Item */ - asn1cSequenceAdd(drbs_toBeModified_item->uLUPTNLInformation_ToBeSetup_List.list, + drbs_toBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_Item; + drbs_toBeModified_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeModified_item_ies->value.present = F1AP_DRBs_ToBeModified_ItemIEs__value_PR_DRBs_ToBeModified_Item; + /* 13.1 SRBs_ToBeModified_Item */ + F1AP_DRBs_ToBeModified_Item_t *drbs_toBeModified_item= + &drbs_toBeModified_item_ies->value.choice.DRBs_ToBeModified_Item; + /* dRBID */ + drbs_toBeModified_item->dRBID = 30L; + /* qoSInformation */ + asn1cCalloc(drbs_toBeModified_item->qoSInformation, tmp); + tmp->present = F1AP_QoSInformation_PR_eUTRANQoS; + tmp->choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); + tmp->choice.eUTRANQoS->qCI = 254L; + /* ULTunnels_ToBeModified_List */ + int maxnoofULTunnels = 1; // 2; + + for (int j=0; j<maxnoofULTunnels; j++) { + /* ULTunnels_ToBeModified_Item */ + asn1cSequenceAdd(drbs_toBeModified_item->uLUPTNLInformation_ToBeSetup_List.list, F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); - uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, + uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, gTPTunnel); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); - OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); + OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", strlen("1204")); - } + } - /* OPTIONAL */ - /* ULConfiguration */ - if (0) { - drbs_toBeModified_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); + /* OPTIONAL */ + /* ULConfiguration */ + if (0) { + drbs_toBeModified_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); + } } } - /* mandatory */ - /* c14. SRBs_ToBeReleased_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie14); - ie14->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_List; - ie14->criticality = F1AP_Criticality_reject; - ie14->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeReleased_List; + /* optional */ + if(0){ + /* c14. SRBs_ToBeReleased_List */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie14); + ie14->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_List; + ie14->criticality = F1AP_Criticality_reject; + ie14->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeReleased_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie14->value.choice.SRBs_ToBeReleased_List.list, + for (int i=0; i<1; i++) { + // + asn1cSequenceAdd(ie14->value.choice.SRBs_ToBeReleased_List.list, F1AP_SRBs_ToBeReleased_ItemIEs_t, srbs_toBeReleased_item_ies); - srbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_Item; - srbs_toBeReleased_item_ies->criticality = F1AP_Criticality_ignore; - srbs_toBeReleased_item_ies->value.present = F1AP_SRBs_ToBeReleased_ItemIEs__value_PR_SRBs_ToBeReleased_Item; - /* 9.1 SRBs_ToBeReleased_Item */ - F1AP_SRBs_ToBeReleased_Item_t *srbs_toBeReleased_item= - &srbs_toBeReleased_item_ies->value.choice.SRBs_ToBeReleased_Item; - /* - sRBID */ - srbs_toBeReleased_item->sRBID = 2L; + srbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_Item; + srbs_toBeReleased_item_ies->criticality = F1AP_Criticality_ignore; + srbs_toBeReleased_item_ies->value.present = F1AP_SRBs_ToBeReleased_ItemIEs__value_PR_SRBs_ToBeReleased_Item; + /* 9.1 SRBs_ToBeReleased_Item */ + F1AP_SRBs_ToBeReleased_Item_t *srbs_toBeReleased_item= + &srbs_toBeReleased_item_ies->value.choice.SRBs_ToBeReleased_Item; + /* - sRBID */ + srbs_toBeReleased_item->sRBID = 2L; + } } - /* mandatory */ - /* c15. DRBs_ToBeReleased_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie15); - ie15->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List; - ie15->criticality = F1AP_Criticality_reject; - ie15->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List; + /* optional */ + if(0){ + /* c15. DRBs_ToBeReleased_List */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie15); + ie15->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List; + ie15->criticality = F1AP_Criticality_reject; + ie15->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List; - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie15->value.choice.DRBs_ToBeReleased_List.list, + for (int i=0; i<1; i++) { + // + asn1cSequenceAdd(ie15->value.choice.DRBs_ToBeReleased_List.list, F1AP_DRBs_ToBeReleased_ItemIEs_t, drbs_toBeReleased_item_ies); - drbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item; - drbs_toBeReleased_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeReleased_item_ies->value.present = F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item; - /* 14.1 SRBs_ToBeReleased_Item */ - F1AP_DRBs_ToBeReleased_Item_t *drbs_toBeReleased_item= - &drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item; - /* dRBID */ - drbs_toBeReleased_item->dRBID = 30L; + drbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item; + drbs_toBeReleased_item_ies->criticality = F1AP_Criticality_reject; + drbs_toBeReleased_item_ies->value.present = F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item; + /* 14.1 SRBs_ToBeReleased_Item */ + F1AP_DRBs_ToBeReleased_Item_t *drbs_toBeReleased_item= + &drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item; + /* dRBID */ + drbs_toBeReleased_item->dRBID = 30L; + } } /* encode */ @@ -1346,7 +1638,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance) { LOG_E(F1AP, "Failed to encode F1 UE CONTEXT_MODIFICATION REQUEST\n"); return -1; } - + f1ap_itti_send_sctp_data_req(true, instance, buffer, len, 0 /* BK: fix me*/); return 0; } @@ -1354,7 +1646,130 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - AssertFatal(1==0,"Not implemented yet\n"); + + MessageDef *msg_p; + F1AP_UEContextModificationResponse_t *container; + F1AP_UEContextModificationResponseIEs_t *ie; + DevAssert(pdu); + msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + f1ap_ue_context_setup_t *f1ap_ue_context_modification_resp = &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg_p); + container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationResponse; + int i; + + /* GNB_CU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + f1ap_ue_context_modification_resp->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID; + + LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_CU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_CU_ue_id); + + /* GNB_DU_UE_F1AP_ID */ + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + f1ap_ue_context_modification_resp->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID; + + LOG_D(F1AP, "f1ap_ue_context_setup_resp->gNB_DU_ue_id is: %d \n", f1ap_ue_context_modification_resp->gNB_DU_ue_id); + + f1ap_ue_context_modification_resp->rnti = + f1ap_get_rnti_by_du_id(CUtype, instance, f1ap_ue_context_modification_resp->gNB_DU_ue_id); + + // DUtoCURRCInformation + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_DUtoCURRCInformation, false); + if(ie!=NULL){ + f1ap_ue_context_modification_resp->du_to_cu_rrc_information = (du_to_cu_rrc_information_t *)calloc(1, sizeof(du_to_cu_rrc_information_t)); + f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig = (uint8_t *)calloc(1,ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); + + memcpy(f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.buf, ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size); + f1ap_ue_context_modification_resp->du_to_cu_rrc_information->cellGroupConfig_length = ie->value.choice.DUtoCURRCInformation.cellGroupConfig.size; + } + + // DRBs_SetupMod_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List, false); + if(ie!=NULL){ + f1ap_ue_context_modification_resp->drbs_to_be_setup_length = ie->value.choice.DRBs_SetupMod_List.list.count; + f1ap_ue_context_modification_resp->drbs_to_be_setup = calloc(f1ap_ue_context_modification_resp->drbs_to_be_setup_length, + sizeof(f1ap_drb_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_resp->drbs_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n"); + for (i = 0; i < f1ap_ue_context_modification_resp->drbs_to_be_setup_length; ++i) { + f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_modification_resp->drbs_to_be_setup[i]; + F1AP_DRBs_SetupMod_Item_t *drbs_setupmod_item_p; + drbs_setupmod_item_p = &((F1AP_DRBs_SetupMod_ItemIEs_t *)ie->value.choice.DRBs_SetupMod_List.list.array[i])->value.choice.DRBs_SetupMod_Item; + drb_p->drb_id = drbs_setupmod_item_p->dRBID; + // TODO in the following, assume only one UP UL TNL is present. + // this matches/assumes OAI CU/DU implementation, can be up to 2! + drb_p->up_dl_tnl_length = 1; + AssertFatal(drbs_setupmod_item_p->dLUPTNLInformation_ToBeSetup_List.list.count > 0, + "no DL UP TNL Information in DRBs to be Setup list\n"); + F1AP_DLUPTNLInformation_ToBeSetup_Item_t *dl_up_tnl_info_p = (F1AP_DLUPTNLInformation_ToBeSetup_Item_t *)drbs_setupmod_item_p->dLUPTNLInformation_ToBeSetup_List.list.array[0]; + F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; + BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); + OCTET_STRING_TO_INT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); + GtpuUpdateTunnelOutgoingTeid(getCxt(CUtype, instance)->gtpInst, + f1ap_ue_context_modification_resp->rnti, + (ebi_t)drbs_setupmod_item_p->dRBID, + drb_p->up_dl_tnl[0].teid); + } + } + // SRBs_FailedToBeSetupMod_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List, false); + if(ie!=NULL){ + f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length = ie->value.choice.SRBs_FailedToBeSetupMod_List.list.count; + f1ap_ue_context_modification_resp->srbs_failed_to_be_setup = calloc(f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length, + sizeof(f1ap_rb_failed_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_resp->srbs_failed_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_resp->srbs_failed_to_be_setup\n"); + for (i = 0; i < f1ap_ue_context_modification_resp->srbs_failed_to_be_setup_length; ++i) { + f1ap_rb_failed_to_be_setup_t *srb_p = &f1ap_ue_context_modification_resp->srbs_failed_to_be_setup[i]; + srb_p->rb_id = ((F1AP_SRBs_FailedToBeSetupMod_Item_t *)ie->value.choice.SRBs_FailedToBeSetupMod_List.list.array[i])->sRBID; + } + + } + // DRBs_FailedToBeSetupMod_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List, false); + if(ie!=NULL){ + f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length = ie->value.choice.DRBs_FailedToBeSetupMod_List.list.count; + f1ap_ue_context_modification_resp->drbs_failed_to_be_setup = calloc(f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length, + sizeof(f1ap_rb_failed_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_resp->drbs_failed_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_resp->drbs_failed_to_be_setup\n"); + for (i = 0; i < f1ap_ue_context_modification_resp->drbs_failed_to_be_setup_length; ++i) { + f1ap_rb_failed_to_be_setup_t *drb_p = &f1ap_ue_context_modification_resp->drbs_failed_to_be_setup[i]; + drb_p->rb_id = ((F1AP_DRBs_FailedToBeSetupMod_Item_t *)ie->value.choice.DRBs_FailedToBeSetupMod_List.list.array[i])->dRBID; + } + } + + // SCell_FailedtoSetupMod_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List, false); + if(ie!=NULL){ + LOG_E (F1AP, "Not supporting handling of SCell_FailedtoSetupMod_List \n"); + } + + // SRBs_Setup_List + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationResponseIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_SRBs_SetupMod_List, false); + if(ie!=NULL){ + f1ap_ue_context_modification_resp->srbs_to_be_setup_length = ie->value.choice.SRBs_SetupMod_List.list.count; + f1ap_ue_context_modification_resp->srbs_to_be_setup = calloc(f1ap_ue_context_modification_resp->srbs_to_be_setup_length, + sizeof(f1ap_srb_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_resp->srbs_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_resp->drbs_setup\n"); + for (i = 0; i < f1ap_ue_context_modification_resp->srbs_to_be_setup_length; ++i) { + f1ap_srb_to_be_setup_t *srb_p = &f1ap_ue_context_modification_resp->srbs_to_be_setup[i]; + F1AP_SRBs_SetupMod_Item_t *srbs_setup_item_p; + srbs_setup_item_p = &((F1AP_SRBs_SetupMod_ItemIEs_t *)ie->value.choice.SRBs_SetupMod_List.list.array[i])->value.choice.SRBs_SetupMod_Item; + srb_p->srb_id = srbs_setup_item_p->sRBID; + srb_p->lcid = srbs_setup_item_p->lCID; + } + } + + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); + return 0; } int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.h b/openair2/F1AP/f1ap_cu_ue_context_management.h index 09af51ec54c2a9328e840e92151895c009fa9513..87563e97b1d39396bb26ad594b83e9c983b2ddae 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.h +++ b/openair2/F1AP/f1ap_cu_ue_context_management.h @@ -72,7 +72,8 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, /* * UE Context Modification (gNB-CU initiated) */ -int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance); +int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, + f1ap_ue_context_setup_t *f1ap_ue_context_modification_req); int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, uint32_t assoc_id, uint32_t stream, diff --git a/openair2/F1AP/f1ap_decoder.c b/openair2/F1AP/f1ap_decoder.c index 6ebf1cc16d483445fe7095cfc633109f1193fc53..60b3f94310e21e85d9e6f33194fb1e1cf4c85b3d 100644 --- a/openair2/F1AP/f1ap_decoder.c +++ b/openair2/F1AP/f1ap_decoder.c @@ -78,6 +78,10 @@ static int f1ap_decode_initiating_message(F1AP_F1AP_PDU_t *pdu) { case F1AP_ProcedureCode_id_UEContextSetup: LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextSetup\n", __func__); break; + + case F1AP_ProcedureCode_id_UEContextModification: + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextModification\n", __func__); + break; // case F1AP_ProcedureCode_id_InitialContextSetup: // res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu); @@ -123,6 +127,10 @@ static int f1ap_decode_successful_outcome(F1AP_F1AP_PDU_t *pdu) { LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextSetup\n", __func__); break; + case F1AP_ProcedureCode_id_UEContextModification: + LOG_I(F1AP, "%s(): F1AP_ProcedureCode_id_UEContextModification\n", __func__); + break; + default: LOG_E(F1AP,"Unknown procedure ID (%d) for successfull outcome message\n", (int)pdu->choice.successfulOutcome->procedureCode); diff --git a/openair2/F1AP/f1ap_default_values.h b/openair2/F1AP/f1ap_default_values.h index 91a11796240a85284a8388b717a16783d7a110b8..7c64614f50af3e6dfa88ff6f504217e338bfb90a 100644 --- a/openair2/F1AP/f1ap_default_values.h +++ b/openair2/F1AP/f1ap_default_values.h @@ -40,7 +40,7 @@ #define ENB_NAME "Eurecom ENB" #define ENB_NAME_FORMAT (ENB_NAME" %u") -#define F1AP_PORT_NUMBER (30923) +#define F1AP_PORT_NUMBER (38472) #define F1AP_SCTP_PPID (62) #endif /* F1AP_DEFAULT_VALUES_H_ */ diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 6d4757be6f6ea0b365cb42b7f33bfbc76222fa3f..367b71fed5f03b267b5d288bc3c4837bde5f2038 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -172,7 +172,20 @@ int DU_send_F1_SETUP_REQUEST(instance_t instance) { MCC_MNC_TO_PLMNID(cell->mcc, cell->mnc, cell->mnc_digit_length, &servedPLMN_item->pLMN_Identity); // // /* - CHOICE NR-MODE-Info */ F1AP_NR_Mode_Info_t *nR_Mode_Info= &served_cell_information->nR_Mode_Info; - + F1AP_ProtocolExtensionContainer_154P34_t *p_154P34=calloc(1,sizeof(* p_154P34)); + servedPLMN_item->iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p_154P34; + asn1cSequenceAdd(p_154P34->list, F1AP_ServedPLMNs_ItemExtIEs_t , served_plmns_itemExtIEs); + served_plmns_itemExtIEs->criticality = F1AP_Criticality_ignore; + served_plmns_itemExtIEs->id = F1AP_ProtocolIE_ID_id_TAISliceSupportList; + served_plmns_itemExtIEs->extensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList; + F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList; + + asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, SliceSupport_item); + INT8_TO_OCTET_STRING(1,&SliceSupport_item->sNSSAI.sST); + asn1cCalloc(SliceSupport_item->sNSSAI.sD, tmp); + INT24_TO_OCTET_STRING(10203,tmp); + //INT24_TO_OCTET_STRING(1,tmp); + if (f1ap_req(false, instance)->fdd_flag) { // FDD nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD; asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info); diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 90ea324a2821479682a1bedd3aa5b2e1665f43f4..c0f8b798397959129dc7953f9a5d8bbed92453ec 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -56,6 +56,7 @@ #include "intertask_interface.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, uint32_t assoc_id, @@ -509,7 +510,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, LOG_I(F1AP, "Received DL RRC Transfer on srb_id %ld\n", srb_id); rlc_op_status_t rlc_status; - boolean_t ret = TRUE; + bool ret = true; mem_block_t *pdcp_pdu_p = NULL; pdcp_pdu_p = get_free_mem_block(rrc_dl_sdu_len, __func__); @@ -539,27 +540,27 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, switch (rlc_status) { case RLC_OP_STATUS_OK: //LOG_I(F1AP, "Data sending request over RLC succeeded!\n"); - ret=TRUE; + ret=true; break; case RLC_OP_STATUS_BAD_PARAMETER: LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); - ret= FALSE; + ret= false; break; case RLC_OP_STATUS_INTERNAL_ERROR: LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); - ret= FALSE; + ret= false; break; case RLC_OP_STATUS_OUT_OF_RESSOURCES: LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); - ret= FALSE; + ret= false; break; default: LOG_W(F1AP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); - ret= FALSE; + ret= false; break; } // switch case @@ -667,9 +668,9 @@ int DU_send_UL_RRC_MESSAGE_TRANSFER(instance_t instance, UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[instance]->UE_info.UE_sched_ctrl[UE_id_mac]); - if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { - UE_scheduling_control->cdrx_waiting_ack = FALSE; - UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration Complete is received + if (UE_scheduling_control->cdrx_waiting_ack == true) { + UE_scheduling_control->cdrx_waiting_ack = false; + UE_scheduling_control->cdrx_configured = true; // Set to TRUE when RRC Connection Reconfiguration Complete is received LOG_I(F1AP, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); } @@ -748,7 +749,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, rnti_t rntiP, const uint8_t *sduP, sdu_size_t sdu_lenP, - const char *sdu2P, + const uint8_t *sdu2P, sdu_size_t sdu2_lenP) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_InitialULRRCMessageTransfer_t *out; @@ -807,9 +808,16 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, ie5->criticality = F1AP_Criticality_reject; ie5->value.present = F1AP_InitialULRRCMessageTransferIEs__value_PR_DUtoCURRCContainer; OCTET_STRING_fromBuf(&ie5->value.choice.DUtoCURRCContainer, - sdu2P, + (const char *)sdu2P, sdu2_lenP); } + /* mandatory */ + /* c6. Transaction ID (integer value) */ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_InitialULRRCMessageTransferIEs_t, ie6); + ie6->id = F1AP_ProtocolIE_ID_id_TransactionID; + ie6->criticality = F1AP_Criticality_ignore; + ie6->value.present = F1AP_F1SetupRequestIEs__value_PR_TransactionID; + ie6->value.choice.TransactionID = F1AP_get_next_transaction_identifier(f1ap_req(false, instanceP)->gNB_DU_id, f1ap_req(false, instanceP)->gNB_DU_id); /* encode */ if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { @@ -979,6 +987,16 @@ int DU_handle_DL_NR_RRC_MESSAGE_TRANSFER(instance_t instance, } } + f1ap_dl_rrc_message_t dl_rrc = { + .rrc_container_length = ie->value.choice.RRCContainer.size, + .rrc_container = ie->value.choice.RRCContainer.buf, + .rnti = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id), + .srb_id = srb_id + }; + int rc = dl_rrc_message(instance, &dl_rrc); + if (rc == 0) + return 0; /* has been handled, otherwise continue below */ + // decode RRC Container and act on the message type AssertFatal(srb_id<3,"illegal srb_id\n"); MessageDef *msg = itti_alloc_new_message(TASK_DU_F1, 0, NR_DU_RRC_DL_INDICATION); diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.h b/openair2/F1AP/f1ap_du_rrc_message_transfer.h index d6f196e38431add79afde8ad4848f4ea50d469d9..b42d731ac702abfc7279b7a6a9296cc529a708a8 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.h +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.h @@ -50,7 +50,7 @@ int DU_send_INITIAL_UL_RRC_MESSAGE_TRANSFER(instance_t instanceP, rnti_t rntiP, const uint8_t *sduP, sdu_size_t sdu_lenP, - const char *sdu2P, + const uint8_t *sdu2P, sdu_size_t sdu2_lenP); #endif /* F1AP_DU_RRC_MESSAGE_TRANSFER_H_ */ diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index c8cfadb99901b6117486da7353961b0ca8eeb78b..f8cf2162201495b90241439e455b4561c4b144b3 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -126,7 +126,7 @@ void *F1AP_DU_task(void *arg) { LOG_I(F1AP, "DU Task Received F1AP_SETUP_REQ\n"); f1ap_setup_req_t *msgSetup=&F1AP_SETUP_REQ(msg); createF1inst(false, myInstance, msgSetup); - getCxt(DUtype, myInstance)->gtpInst=du_create_gtpu_instance_to_cu(msgSetup->CU_f1_ip_address.ipv4_address, + getCxt(DUtype, myInstance)->gtpInst=du_create_gtpu_instance_to_cu(msgSetup->CU_f1_ip_address.ipv4_address, //"172.21.6.9", //"172.21.10.9",//"172.21.9.5", //msgSetup->CU_f1_ip_address.ipv4_address, //"192.168.18.91" msgSetup->CUport, msgSetup->DU_f1_ip_address.ipv4_address, msgSetup->DUport); @@ -175,7 +175,7 @@ void *F1AP_DU_task(void *arg) { break; case F1AP_UL_RRC_MESSAGE: // to rrc - LOG_I(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); + LOG_D(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n"); if (RC.nrrrc && RC.nrrrc[0]->node_type == ngran_gNB_DU) { DU_send_UL_NR_RRC_MESSAGE_TRANSFER(myInstance, @@ -191,6 +191,11 @@ void *F1AP_DU_task(void *arg) { DU_send_UE_CONTEXT_SETUP_RESPONSE(myInstance, &F1AP_UE_CONTEXT_SETUP_RESP(msg)); break; + case F1AP_UE_CONTEXT_MODIFICATION_RESP: + LOG_I(F1AP, "DU task received itti message from RRC for F1AP_UE_CONTEXT_MODIFICATION_RESP message generation \n"); + DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(myInstance, &F1AP_UE_CONTEXT_MODIFICATION_RESP(msg)); + break; + case F1AP_UE_CONTEXT_RELEASE_REQ: // from MAC LOG_I(F1AP, "DU Task Received F1AP_UE_CONTEXT_RELEASE_REQ\n"); DU_send_UE_CONTEXT_RELEASE_REQUEST(myInstance, diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index e19f077592aa33d8cd763a3a37f5c15a57b2d060..cb15862921412be5bfd085cc01ecbcf92121db3e 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -42,16 +42,16 @@ #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" #include <openair3/ocp-gtpu/gtp_itf.h> -boolean_t lteDURecvCb( protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) { +bool lteDURecvCb(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id) { // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__); memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP); @@ -131,6 +131,19 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, f1ap_ue_context_setup_req->cellULConfigured = NULL; } + F1AP_UEContextSetupRequestIEs_t *ieCuRrcInfo; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieCuRrcInfo, container, + F1AP_ProtocolIE_ID_id_CUtoDURRCInformation, false); + if(ieCuRrcInfo!=NULL){ + f1ap_ue_context_setup_req->cu_to_du_rrc_information = (cu_to_du_rrc_information_t *)calloc(1,sizeof(cu_to_du_rrc_information_t)); + if(ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList!=NULL){ + f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList = (uint8_t *)calloc(1,ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size); + memcpy(f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->buf, ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size); + f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length = ieCuRrcInfo->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList->size; + LOG_I(F1AP, "Size f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length: %d \n", f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); + } + } + /* DRB */ F1AP_UEContextSetupRequestIEs_t *ieDrb; F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieDrb, container, @@ -174,14 +187,16 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, transport_layer_addr_t addr; memcpy(addr.buffer, &drb_p->up_ul_tnl[0].tl_address, sizeof(drb_p->up_ul_tnl[0].tl_address)); addr.length=sizeof(drb_p->up_ul_tnl[0].tl_address)*8; - drb_p->up_dl_tnl[0].teid=newGtpuCreateTunnel(INSTANCE_DEFAULT, - f1ap_ue_context_setup_req->rnti, - drb_p->drb_id, - drb_p->drb_id, - drb_p->up_ul_tnl[0].teid, - addr, - drb_p->up_ul_tnl[0].port, - lteDURecvCb); + drb_p->up_dl_tnl[0].teid = newGtpuCreateTunnel(INSTANCE_DEFAULT, + f1ap_ue_context_setup_req->rnti, + drb_p->drb_id, + drb_p->drb_id, + drb_p->up_ul_tnl[0].teid, + -1, // no qfi + addr, + drb_p->up_ul_tnl[0].port, + lteDURecvCb, + NULL); drb_p->up_dl_tnl_length++; } } @@ -218,17 +233,8 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, f1ap_ue_context_setup_req->rrc_container = malloc(ieRRC->value.choice.RRCContainer.size); memcpy(f1ap_ue_context_setup_req->rrc_container, ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size); + f1ap_ue_context_setup_req->rrc_container_length = ieRRC->value.choice.RRCContainer.size; // AssertFatal(0, "check configuration, send to appropriate handler\n"); - protocol_ctxt_t ctxt; - // decode RRC Container and act on the message type - //FIXME - //rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance, du_ue_f1ap_id); - ctxt.instance = instance; - ctxt.instance = instance; - ctxt.enb_flag = 1; - mem_block_t *pdcp_pdu_p = get_free_mem_block(ieRRC->value.choice.RRCContainer.size, __func__); - memcpy(&pdcp_pdu_p->data[0], ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size); - du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, ieRRC->value.choice.RRCContainer.size, pdcp_pdu_p); } else { LOG_E(F1AP, " RRCContainer in UEContextSetupRequestIEs size id 0\n"); } @@ -245,7 +251,7 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, return 0; } -int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *req) { +int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextSetupResponse_t *out; uint8_t *buffer=NULL; @@ -264,41 +270,42 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextSetupResponseIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = req->gNB_CU_ue_id; + ie1->value.choice.GNB_CU_UE_F1AP_ID = resp->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, req->rnti); + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, resp->rnti); + /* mandatory */ /* c3. DUtoCURRCInformation */ - //if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation; - ie3->criticality = F1AP_Criticality_reject; - ie3->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DUtoCURRCInformation; - { - /* cellGroupConfig */ - OCTET_STRING_fromBuf(&ie3->value.choice.DUtoCURRCInformation.cellGroupConfig, (const char *)req->du_to_cu_rrc_information, - req->du_to_cu_rrc_information_length); + if(resp->du_to_cu_rrc_information){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DUtoCURRCInformation; + if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){ + /* cellGroupConfig */ + OCTET_STRING_fromBuf(&ie3->value.choice.DUtoCURRCInformation.cellGroupConfig, (const char *)resp->du_to_cu_rrc_information->cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig_length); + } /* OPTIONAL */ /* measGapConfig */ - if (0) { - asn1cCalloc(ie3->value.choice.DUtoCURRCInformation.measGapConfig, tmp); - OCTET_STRING_fromBuf(tmp, "asdsa", strlen("asdsa")); + if (resp->du_to_cu_rrc_information->measGapConfig!=NULL) { + OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.measGapConfig, (const char *)resp->du_to_cu_rrc_information->measGapConfig, + resp->du_to_cu_rrc_information->measGapConfig_length); } /* OPTIONAL */ /* requestedP_MaxFR1 */ - if (0) { - asn1cCalloc(ie3->value.choice.DUtoCURRCInformation.requestedP_MaxFR1, tmp); - OCTET_STRING_fromBuf(tmp, "asdsa", strlen("asdsa")); + if (resp->du_to_cu_rrc_information->requestedP_MaxFR1!=NULL) { + OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.requestedP_MaxFR1, (const char *)resp->du_to_cu_rrc_information->requestedP_MaxFR1, + resp->du_to_cu_rrc_information->requestedP_MaxFR1_length); } } - //} /* optional */ /* c4. C_RNTI */ @@ -308,7 +315,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup ie4->criticality = F1AP_Criticality_ignore; ie4->value.present = F1AP_UEContextSetupResponseIEs__value_PR_C_RNTI; //C_RNTI_TO_BIT_STRING(rntiP, &ie->value.choice.C_RNTI); - ie4->value.choice.C_RNTI=req->rnti; + ie4->value.choice.C_RNTI=resp->rnti; LOG_E(F1AP,"RNTI to code!\n"); } @@ -335,46 +342,48 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup /* mandatory */ /* c7. DRBs_Setup_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie7); - ie7->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_List; - ie7->criticality = F1AP_Criticality_ignore; - ie7->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List; - - for (int i=0; i< req->drbs_to_be_setup_length; i++) { - // - asn1cSequenceAdd(ie7->value.choice.DRBs_Setup_List.list, - F1AP_DRBs_Setup_ItemIEs_t, drbs_setup_item_ies); - drbs_setup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_Item; - drbs_setup_item_ies->criticality = F1AP_Criticality_ignore; - drbs_setup_item_ies->value.present = F1AP_SRBs_FailedToBeSetup_ItemIEs__value_PR_SRBs_FailedToBeSetup_Item; - /* 7.1 DRBs_Setup_Item */ - /* ADD */ - F1AP_DRBs_Setup_Item_t *drbs_setup_item=&drbs_setup_item_ies->value.choice.DRBs_Setup_Item; - /* dRBID */ - drbs_setup_item->dRBID = req->drbs_to_be_setup[i].drb_id; + if(resp->drbs_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie7); + ie7->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_List; + ie7->criticality = F1AP_Criticality_ignore; + ie7->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List; + for (int i=0; i< resp->drbs_to_be_setup_length; i++) { + // + asn1cSequenceAdd(ie7->value.choice.DRBs_Setup_List.list, + F1AP_DRBs_Setup_ItemIEs_t, drbs_setup_item_ies); + drbs_setup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_Item; + drbs_setup_item_ies->criticality = F1AP_Criticality_ignore; + drbs_setup_item_ies->value.present = F1AP_DRBs_Setup_ItemIEs__value_PR_DRBs_Setup_Item; + /* 7.1 DRBs_Setup_Item */ + /* ADD */ + F1AP_DRBs_Setup_Item_t *drbs_setup_item=&drbs_setup_item_ies->value.choice.DRBs_Setup_Item; + /* dRBID */ + drbs_setup_item->dRBID = resp->drbs_to_be_setup[i].drb_id; - /* OPTIONAL */ - /* lCID */ - //drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t)); - //drbs_setup_item.lCID = 1L; + /* OPTIONAL */ + /* lCID */ + //drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t)); + //drbs_setup_item.lCID = 1L; - for (int j=0; j<req->drbs_to_be_setup[i].up_dl_tnl_length; j++) { - /* ADD */ - asn1cSequenceAdd(drbs_setup_item->dLUPTNLInformation_ToBeSetup_List.list, + for (int j=0; j<resp->drbs_to_be_setup[i].up_dl_tnl_length; j++) { + /* ADD */ + asn1cSequenceAdd(drbs_setup_item->dLUPTNLInformation_ToBeSetup_List.list, F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); - dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - /* gTPTunnel */ - asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); - /* transportLayerAddress */ - struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(false,instance)->setupReq.DU_f1_ip_address.ipv4_address, - &addr.sin_addr.s_addr); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, - &gTPTunnel->transportLayerAddress); - /* gTP_TEID */ - INT32_TO_OCTET_STRING(req->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); - } // for j - } // for i + dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + /* gTPTunnel */ + asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); + /* transportLayerAddress */ + struct sockaddr_in addr= {0}; + inet_pton(AF_INET, getCxt(false,instance)->setupReq.DU_f1_ip_address.ipv4_address, + &addr.sin_addr.s_addr); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, + &gTPTunnel->transportLayerAddress); + /* gTP_TEID */ + INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + } // for j + } // for i + + } /* mandatory */ /* c8. SRBs_FailedToBeSetup_List */ @@ -387,7 +396,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup for (int i=0; i<1; i++) { // asn1cSequenceAdd(ie8->value.choice.SRBs_FailedToBeSetup_List.list, - F1AP_SRBs_FailedToBeSetup_ItemIEs_t, srbs_failedToBeSetup_item_ies); + F1AP_SRBs_FailedToBeSetup_ItemIEs_t, srbs_failedToBeSetup_item_ies); srbs_failedToBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetup_Item; srbs_failedToBeSetup_item_ies->criticality = F1AP_Criticality_ignore; srbs_failedToBeSetup_item_ies->value.present = F1AP_SRBs_FailedToBeSetup_ItemIEs__value_PR_SRBs_FailedToBeSetup_Item; @@ -524,12 +533,13 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup /* mandatory */ /* c11. SRBs_Setup_List */ + if(resp->srbs_to_be_setup_length > 0){ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie11); ie11->id = F1AP_ProtocolIE_ID_id_SRBs_Setup_List; ie11->criticality = F1AP_Criticality_ignore; ie11->value.present = F1AP_UEContextSetupResponseIEs__value_PR_SRBs_Setup_List; - for (int i=0; i< req->srbs_to_be_setup_length; i++) {// + for (int i=0; i< resp->srbs_to_be_setup_length; i++) {// asn1cSequenceAdd(ie11->value.choice.SRBs_Setup_List.list, F1AP_SRBs_Setup_ItemIEs_t, srbs_setup_item_ies); srbs_setup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_Setup_Item; @@ -539,7 +549,8 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup /* ADD */ F1AP_SRBs_Setup_Item_t *srbs_setup_item=&srbs_setup_item_ies->value.choice.SRBs_Setup_Item; /* sRBID */ - srbs_setup_item->sRBID = req->srbs_to_be_setup[i].srb_id; + srbs_setup_item->sRBID = resp->srbs_to_be_setup[i].srb_id; + } } /* Optional */ @@ -581,6 +592,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, f1ap_ue_context_setup getCxt(false, instance)->default_sctp_stream_id); return 0; } + int DU_send_UE_CONTEXT_SETUP_FAILURE(instance_t instance) { AssertFatal(1==0,"Not implemented yet\n"); } @@ -658,7 +670,7 @@ int DU_send_UE_CONTEXT_RELEASE_REQUEST(instance_t instance, getCxt(false, instance)->default_sctp_stream_id); return 0; } -int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, +/*int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { @@ -667,14 +679,14 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, protocol_ctxt_t ctxt; DevAssert(pdu); container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand; - /* GNB_CU_UE_F1AP_ID */ + // GNB_CU_UE_F1AP_ID F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); ctxt.rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID); ctxt.instance = instance; ctxt.module_id = instance; ctxt.enb_flag = 1; - /* GNB_DU_UE_F1AP_ID */ + // GNB_DU_UE_F1AP_ID F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); const rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance, @@ -694,20 +706,21 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, LOG_E(F1AP,"Not found rnti: %x\n", rnti); } else { for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) { - if (RC.mac[instance]->UE_info.active[n] == TRUE + if (RC.mac[instance]->UE_info.active[n] == true && rnti == UE_RNTI(instance, n)) { UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync; break; } } } - /* We don't need the Cause */ - /* Optional RRC Container: if present, send to UE */ + + // We don't need the Cause + // Optional RRC Container: if present, send to UE F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, false); if (ie && !UE_out_of_sync) { - /* RRC message and UE is reachable, send message */ + // RRC message and UE is reachable, send message const sdu_size_t sdu_len = ie->value.choice.RRCContainer.size; mem_block_t *pdu_p = NULL; pdu_p = get_free_mem_block(sdu_len, __func__); @@ -758,8 +771,8 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.instance], ctxt.rnti); if (ue_context_p && !UE_out_of_sync) { - /* UE exists and is in sync so we start a timer before releasing the - * connection */ + // UE exists and is in sync so we start a timer before releasing the + // connection pthread_mutex_lock(&rrc_release_freelist); for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { @@ -783,19 +796,198 @@ int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, pthread_mutex_unlock(&rrc_release_freelist); ue_context_p->ue_context.ue_release_timer_s1 = 0; } else if (ue_context_p && UE_out_of_sync) { - /* UE exists and is out of sync, drop the connection */ + // UE exists and is out of sync, drop the connection mac_eNB_rrc_ul_failure(instance, 0, 0, 0, rnti); } else { LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", rnti); } - /* TODO send this once the connection has really been released */ + // TODO send this once the connection has really been released + f1ap_ue_context_release_cplt_t cplt; + cplt.rnti = ctxt.rnti; + DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt); + return 0; + } +}*/ + + +int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, + uint32_t assoc_id, + uint32_t stream, + F1AP_F1AP_PDU_t *pdu) { + F1AP_UEContextReleaseCommand_t *container; + F1AP_UEContextReleaseCommandIEs_t *ie; + protocol_ctxt_t ctxt; + + /* ITTI message to NR-RRC for the case of gNB-DU */ + MessageDef *msg_p; // message to NR-RRC + msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_RELEASE_CMD); + f1ap_ue_context_release_req_t *f1ap_ue_context_release_cmd = &F1AP_UE_CONTEXT_RELEASE_CMD(msg_p); + + + DevAssert(pdu); + container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand; + // GNB_CU_UE_F1AP_ID + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + if(RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU){ + f1ap_ue_context_release_cmd->rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID); + } + else{ + ctxt.rnti = f1ap_get_rnti_by_cu_id(DUtype, instance, ie->value.choice.GNB_CU_UE_F1AP_ID); + ctxt.instance = instance; + ctxt.module_id = instance; + ctxt.enb_flag = 1; + } + // GNB_DU_UE_F1AP_ID + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + const rnti_t rnti = f1ap_get_rnti_by_du_id(DUtype, instance, + ie->value.choice.GNB_DU_UE_F1AP_ID); + if(RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU){ + AssertFatal(f1ap_ue_context_release_cmd->rnti == rnti, + "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", + rnti, f1ap_ue_context_release_cmd->rnti); + } + else{ + AssertFatal(ctxt.rnti == rnti, + "RNTI obtained through DU ID (%x) is different from CU ID (%x)\n", + rnti, ctxt.rnti); + } + int UE_out_of_sync = 0; + + if(RC.rrc && RC.rrc[instance]->node_type == ngran_eNB_DU){ + for (int n = 0; n < MAX_MOBILES_PER_ENB; ++n) { + if (RC.mac[instance]->UE_info.active[n] == true + && rnti == UE_RNTI(instance, n)) { + UE_out_of_sync = RC.mac[instance]->UE_info.UE_sched_ctrl[n].ul_out_of_sync; + break; + } + } + } + + // We don't need the Cause + // Optional RRC Container: if present, send to UE + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_RRCContainer, false); + + if (ie && !UE_out_of_sync && RC.rrc && RC.rrc[instance]->node_type == ngran_eNB_DU) { + // RRC message and UE is reachable, send message + const sdu_size_t sdu_len = ie->value.choice.RRCContainer.size; + mem_block_t *pdu_p = NULL; + pdu_p = get_free_mem_block(sdu_len, __func__); + memcpy(&pdu_p->data[0], ie->value.choice.RRCContainer.buf, sdu_len); + rlc_op_status_t rlc_status = rlc_data_req(&ctxt + , 1 + , MBMS_FLAG_NO + , 1 // SRB 1 correct? + , 0 + , 0 + , sdu_len + , pdu_p + ,NULL + ,NULL + ); + + switch (rlc_status) { + case RLC_OP_STATUS_OK: + break; + + case RLC_OP_STATUS_BAD_PARAMETER: + LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); + break; + + case RLC_OP_STATUS_INTERNAL_ERROR: + LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); + break; + + case RLC_OP_STATUS_OUT_OF_RESSOURCES: + LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); + break; + + default: + LOG_W(F1AP, "RLC returned an unknown status code after F1AP placed " + "the order to send some data (Status Code:%d)\n", rlc_status); + break; + } + } + else if(ie && RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) { + f1ap_ue_context_release_cmd->rrc_container = malloc(ie->value.choice.RRCContainer.size); + memcpy(f1ap_ue_context_release_cmd->rrc_container, + ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size); + } + + if (RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU) { + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_Cause, true); + switch (ie->value.choice.Cause.present){ + case F1AP_Cause_PR_radioNetwork: + LOG_W (F1AP, "UE context release command cause is due to radioNetwork with specific code: %ld\n",ie->value.choice.Cause.choice.radioNetwork); + f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_RADIO_NETWORK; + break; + case F1AP_Cause_PR_transport: + LOG_W (F1AP, "UE context release command cause is due to transport with specific code: %ld\n",ie->value.choice.Cause.choice.transport); + f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_TRANSPORT; + break; + case F1AP_Cause_PR_protocol: + LOG_W (F1AP, "UE context release command cause is due to protocol with specific code: %ld\n",ie->value.choice.Cause.choice.protocol); + f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_PROTOCOL; + break; + case F1AP_Cause_PR_misc: + LOG_W (F1AP, "UE context release command cause is misc with specific code: %ld \n",ie->value.choice.Cause.choice.misc); + f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_MISC; + break; + default: + LOG_W(F1AP, "Unknown cause for UE context release command\n"); + break; + + } + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); + return 0; + } else { + struct rrc_eNB_ue_context_s *ue_context_p; + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.instance], ctxt.rnti); + + if (ue_context_p && !UE_out_of_sync) { + // UE exists and is in sync so we start a timer before releasing the + // connection + pthread_mutex_lock(&rrc_release_freelist); + + for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { + if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) { + if (ue_context_p->ue_context.ue_release_timer_s1 > 0) + rrc_release_info.RRC_release_ctrl[release_num].flag = 1; + else + rrc_release_info.RRC_release_ctrl[release_num].flag = 2; + + rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt.rnti; + LOG_D(F1AP, "add rrc_release_info RNTI %x\n", ctxt.rnti); + // TODO: how to provide the correct MUI? + rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = 0; + rrc_release_info.num_UEs++; + LOG_D(RRC,"Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n",release_num, + ctxt.rnti, 0, rrc_release_info.RRC_release_ctrl[release_num].flag); + break; + } + } + + pthread_mutex_unlock(&rrc_release_freelist); + ue_context_p->ue_context.ue_release_timer_s1 = 0; + } else if (ue_context_p && UE_out_of_sync) { + // UE exists and is out of sync, drop the connection + mac_eNB_rrc_ul_failure(instance, 0, 0, 0, rnti); + } else { + LOG_E(F1AP, "no ue_context for RNTI %x, acknowledging release\n", rnti); + } + + // TODO send this once the connection has really been released f1ap_ue_context_release_cplt_t cplt; cplt.rnti = ctxt.rnti; DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance, &cplt); return 0; } } + int DU_send_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, f1ap_ue_context_release_cplt_t *cplt) { F1AP_F1AP_PDU_t pdu= {0}; @@ -890,10 +1082,162 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) { - AssertFatal(1==0,"Not implemented yet\n"); + + MessageDef *msg_p; // message to RRC + F1AP_UEContextModificationRequest_t *container; + int i; + DevAssert(pdu); + msg_p = itti_alloc_new_message(TASK_DU_F1, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); + f1ap_ue_context_setup_t *f1ap_ue_context_modification_req = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); + container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequest; + + /* mandatory */ + /* GNB_CU_UE_F1AP_ID */ + F1AP_UEContextModificationRequestIEs_t *ieCU; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieCU, container, + F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true); + f1ap_ue_context_modification_req->gNB_CU_ue_id = ieCU->value.choice.GNB_CU_UE_F1AP_ID; + + /* mandatory */ + /* GNB_DU_UE_F1AP_ID */ + F1AP_UEContextModificationRequestIEs_t *ieDU_UE; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieDU_UE, container, + F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true); + f1ap_ue_context_modification_req->gNB_DU_ue_id = ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID; + f1ap_ue_context_modification_req->rnti = f1ap_get_rnti_by_du_id(DUtype, instance, f1ap_ue_context_modification_req->gNB_DU_ue_id); + + if(f1ap_ue_context_modification_req->rnti<0) + LOG_E(F1AP, "Could not retrieve UE rnti based on the DU UE id \n"); + else + LOG_I(F1AP, "Retrieved rnti is: %d \n", f1ap_ue_context_modification_req->rnti); + + /* SRB */ + F1AP_UEContextModificationRequestIEs_t *ieSrb; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieSrb, container, + F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List, false); + + if(ieSrb != NULL) { + f1ap_ue_context_modification_req->srbs_to_be_setup_length = ieSrb->value.choice.SRBs_ToBeSetupMod_List.list.count; + f1ap_ue_context_modification_req->srbs_to_be_setup = calloc(f1ap_ue_context_modification_req->srbs_to_be_setup_length, + sizeof(f1ap_srb_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_req->srbs_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_req->srbs_to_be_setup\n"); + + for (i = 0; i < f1ap_ue_context_modification_req->srbs_to_be_setup_length; ++i) { + f1ap_srb_to_be_setup_t *srb_p = &f1ap_ue_context_modification_req->srbs_to_be_setup[i]; + F1AP_SRBs_ToBeSetupMod_Item_t *srbs_tobesetupmod_item_p; + srbs_tobesetupmod_item_p = &((F1AP_SRBs_ToBeSetupMod_ItemIEs_t *)ieSrb->value.choice.SRBs_ToBeSetupMod_List.list.array[i])->value.choice.SRBs_ToBeSetupMod_Item; + srb_p->srb_id = srbs_tobesetupmod_item_p->sRBID; + } + } + + /* DRB */ + F1AP_UEContextModificationRequestIEs_t *ieDrb; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieDrb, container, + F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List, false); + + if(ieDrb!=NULL) { + f1ap_ue_context_modification_req->drbs_to_be_setup_length = ieDrb->value.choice.DRBs_ToBeSetupMod_List.list.count; + f1ap_ue_context_modification_req->drbs_to_be_setup = calloc(f1ap_ue_context_modification_req->drbs_to_be_setup_length, + sizeof(f1ap_drb_to_be_setup_t)); + AssertFatal(f1ap_ue_context_modification_req->drbs_to_be_setup, + "could not allocate memory for f1ap_ue_context_setup_req->drbs_to_be_setup\n"); + + for (i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_setup_length; ++i) { + f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_modification_req->drbs_to_be_setup[i]; + F1AP_DRBs_ToBeSetupMod_Item_t *drbs_tobesetupmod_item_p = + &((F1AP_DRBs_ToBeSetupMod_ItemIEs_t *)ieDrb->value.choice.DRBs_ToBeSetupMod_List.list.array[i])->value.choice.DRBs_ToBeSetupMod_Item; + drb_p->drb_id = drbs_tobesetupmod_item_p->dRBID; + /* TODO in the following, assume only one UP UL TNL is present. + * this matches/assumes OAI CU implementation, can be up to 2! */ + drb_p->up_ul_tnl_length = 1; + AssertFatal(drbs_tobesetupmod_item_p->uLUPTNLInformation_ToBeSetup_List.list.count > 0, + "no UL UP TNL Information in DRBs to be Setup list\n"); + F1AP_ULUPTNLInformation_ToBeSetup_Item_t *ul_up_tnl_info_p = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)drbs_tobesetupmod_item_p->uLUPTNLInformation_ToBeSetup_List.list.array[0]; + F1AP_GTPTunnel_t *ul_up_tnl0 = ul_up_tnl_info_p->uLUPTNLInformation.choice.gTPTunnel; + BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&ul_up_tnl0->transportLayerAddress, drb_p->up_ul_tnl[0].tl_address); + OCTET_STRING_TO_INT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].teid); + // 3GPP assumes GTP-U is on port 2152, but OAI is configurable + drb_p->up_ul_tnl[0].port=getCxt(false,instance)->setupReq.CUport; + + switch (drbs_tobesetupmod_item_p->rLCMode) { + case F1AP_RLCMode_rlc_am: + drb_p->rlc_mode = RLC_MODE_AM; + break; + + default: + drb_p->rlc_mode = RLC_MODE_TM; + break; + } + if (!(RC.nrrrc && RC.nrrrc[instance]->node_type == ngran_gNB_DU)) { + transport_layer_addr_t addr; + memcpy(addr.buffer, &drb_p->up_ul_tnl[0].tl_address, sizeof(drb_p->up_ul_tnl[0].tl_address)); + addr.length=sizeof(drb_p->up_ul_tnl[0].tl_address)*8; + drb_p->up_dl_tnl[0].teid = newGtpuCreateTunnel(INSTANCE_DEFAULT, + f1ap_ue_context_modification_req->rnti, + drb_p->drb_id, + drb_p->drb_id, + drb_p->up_ul_tnl[0].teid, + -1, // no qfi + addr, + drb_p->up_ul_tnl[0].port, + lteDURecvCb, + NULL); + drb_p->up_dl_tnl_length++; + } + } + } + /* RRC Reconfiguration Complete indicator */ + F1AP_UEContextModificationRequestIEs_t *ieReconf; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieReconf, container, + F1AP_ProtocolIE_ID_id_RRCReconfigurationCompleteIndicator, false); + + if(ieReconf) { + switch(ieReconf->value.choice.RRCReconfigurationCompleteIndicator){ + case F1AP_RRCReconfigurationCompleteIndicator_true: + f1ap_ue_context_modification_req->ReconfigComplOutcome = RRCreconf_success; + break; + + case F1AP_RRCReconfigurationCompleteIndicator_failure: + f1ap_ue_context_modification_req->ReconfigComplOutcome = RRCreconf_failure; + break; + } + } + + /* RRCContainer */ + F1AP_UEContextModificationRequestIEs_t *ieRRC; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieRRC, container, + F1AP_ProtocolIE_ID_id_RRCContainer, false); + + if (ieRRC) { + /* correct here */ + if ( ieRRC->value.choice.RRCContainer.size ) { + f1ap_ue_context_modification_req->rrc_container = malloc(ieRRC->value.choice.RRCContainer.size); + memcpy(f1ap_ue_context_modification_req->rrc_container, + ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size); + protocol_ctxt_t ctxt; + // decode RRC Container and act on the message type + ctxt.rnti = f1ap_ue_context_modification_req->rnti; + ctxt.instance = instance; + ctxt.module_id = instance; + ctxt.enb_flag = 1; + ctxt.eNB_index = instance; + mem_block_t *pdcp_pdu_p = get_free_mem_block(ieRRC->value.choice.RRCContainer.size, __func__); + memcpy(&pdcp_pdu_p->data[0], ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size); + du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, ieRRC->value.choice.RRCContainer.size, pdcp_pdu_p); + } else { + LOG_E(F1AP, " RRCContainer in UEContextModificationRequestIEs size id 0\n"); + } + } else { + LOG_W(F1AP, "can't find RRCContainer in UEContextModificationRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer); + } + + itti_send_msg_to_task(TASK_RRC_GNB, instance, msg_p); + return 0; } + //void DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(F1AP_UEContextModificationResponse_t *UEContextModificationResponse) { -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp) { F1AP_F1AP_PDU_t pdu= {0}; F1AP_UEContextModificationResponse_t *out; uint8_t *buffer=NULL; @@ -912,14 +1256,14 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; ie1->criticality = F1AP_Criticality_reject; ie1->value.present = F1AP_UEContextModificationResponseIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = 126L; + ie1->value.choice.GNB_CU_UE_F1AP_ID = resp->gNB_CU_ue_id; /* mandatory */ /* c2. GNB_DU_UE_F1AP_ID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie2); ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; ie2->criticality = F1AP_Criticality_reject; ie2->value.present = F1AP_UEContextModificationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = 651L; + ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_get_du_ue_f1ap_id(DUtype, instance, resp->rnti); /* optional */ /* c3. ResourceCoordinationTransferContainer */ @@ -934,184 +1278,205 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { /* optional */ /* c4. DUtoCURRCInformation */ - if (0) { + if(resp->du_to_cu_rrc_information!=NULL){ asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie4); ie4->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation; ie4->criticality = F1AP_Criticality_reject; ie4->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DUtoCURRCInformation; - OCTET_STRING_fromBuf(&ie4->value.choice.DUtoCURRCInformation.cellGroupConfig, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); + if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){ + /* cellGroupConfig */ + OCTET_STRING_fromBuf(&ie4->value.choice.DUtoCURRCInformation.cellGroupConfig, (const char *)resp->du_to_cu_rrc_information->cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig_length); + } /* OPTIONAL */ - if (1) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie41); - ie41->value.choice.DUtoCURRCInformation.measGapConfig = (F1AP_MeasGapConfig_t *)calloc(1, sizeof(F1AP_MeasGapConfig_t)); - OCTET_STRING_fromBuf( ie41->value.choice.DUtoCURRCInformation.measGapConfig, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); + /* measGapConfig */ + if (resp->du_to_cu_rrc_information->measGapConfig!=NULL) { + OCTET_STRING_fromBuf(ie4->value.choice.DUtoCURRCInformation.measGapConfig, (const char *)resp->du_to_cu_rrc_information->measGapConfig, + resp->du_to_cu_rrc_information->measGapConfig_length); } - } - /* mandatory */ - /* c5. DRBs_SetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie5); - ie5->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List; - ie5->criticality = F1AP_Criticality_reject; - ie5->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_SetupMod_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie5->value.choice.DRBs_SetupMod_List.list, - F1AP_DRBs_SetupMod_ItemIEs_t, drbs_setupMod_item_ies); - drbs_setupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_Item; - drbs_setupMod_item_ies->criticality = F1AP_Criticality_reject; - drbs_setupMod_item_ies->value.present = F1AP_DRBs_SetupMod_ItemIEs__value_PR_DRBs_SetupMod_Item; - /* 10.1 DRBs_SetupMod_Item */ - F1AP_DRBs_SetupMod_Item_t *drbs_setupMod_item=&drbs_setupMod_item_ies->value.choice.DRBs_SetupMod_Item; - /* dRBID */ - drbs_setupMod_item->dRBID = 30L; - /* DLTunnels_SetupMod_List */ - int maxnoofDLUPTNLInformation = 1; // 2; - - for (int j=0; j<maxnoofDLUPTNLInformation; j++) { - /* DLTunnels_ToBeSetup_Item */ - asn1cSequenceAdd(ie5->value.choice.DRBs_SetupMod_List.list, - F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); - dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, - gTPTunnel); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); - OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", - strlen("1204")); + /* OPTIONAL */ + /* requestedP_MaxFR1 */ + if (resp->du_to_cu_rrc_information->requestedP_MaxFR1!=NULL) { + OCTET_STRING_fromBuf(ie4->value.choice.DUtoCURRCInformation.requestedP_MaxFR1, (const char *)resp->du_to_cu_rrc_information->requestedP_MaxFR1, + resp->du_to_cu_rrc_information->requestedP_MaxFR1_length); } } - /* mandatory */ + + /* optional */ + /* c5. DRBs_Setup_List */ + if(resp->drbs_to_be_setup_length > 0) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie5); + ie5->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List; + ie5->criticality = F1AP_Criticality_ignore; + ie5->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_SetupMod_List; + for (int i=0; i< resp->drbs_to_be_setup_length; i++) { + asn1cSequenceAdd(ie5->value.choice.DRBs_SetupMod_List.list, F1AP_DRBs_SetupMod_ItemIEs_t, drbs_setupmod_item_ies); + drbs_setupmod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_Item; + drbs_setupmod_item_ies->criticality = F1AP_Criticality_ignore; + drbs_setupmod_item_ies->value.present = F1AP_DRBs_SetupMod_ItemIEs__value_PR_DRBs_SetupMod_Item; + /* 7.1 DRBs_Setup_Item */ + /* ADD */ + F1AP_DRBs_SetupMod_Item_t *drbs_setupmod_item=&drbs_setupmod_item_ies->value.choice.DRBs_SetupMod_Item; + /* dRBID */ + drbs_setupmod_item->dRBID = resp->drbs_to_be_setup[i].drb_id; + + for (int j=0; j<resp->drbs_to_be_setup[i].up_dl_tnl_length; j++) { + /* ADD */ + asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list, + F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); + dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + /* gTPTunnel */ + asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); + /* transportLayerAddress */ + struct sockaddr_in addr= {0}; + inet_pton(AF_INET, getCxt(false,instance)->setupReq.DU_f1_ip_address.ipv4_address, + &addr.sin_addr.s_addr); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, + &gTPTunnel->transportLayerAddress); + /* gTP_TEID */ + INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + } // for j + } // for i + } + + /* optional */ /* c6. DRBs_Modified_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie6); - ie6->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_List; - ie6->criticality = F1AP_Criticality_reject; - ie6->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_Modified_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie6->value.choice.DRBs_Modified_List.list, - F1AP_DRBs_Modified_ItemIEs_t, drbs_modified_item_ies); - drbs_modified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_Item; - drbs_modified_item_ies->criticality = F1AP_Criticality_reject; - drbs_modified_item_ies->value.present = F1AP_DRBs_Modified_ItemIEs__value_PR_DRBs_Modified_Item; - /* 13.1 SRBs_modified_Item */ - F1AP_DRBs_Modified_Item_t *drbs_modified_item= - &drbs_modified_item_ies->value.choice.DRBs_Modified_Item; - /* dRBID */ - drbs_modified_item->dRBID = 25L; - /* ULTunnels_Modified_List */ - int maxnoofULTunnels = 1; // 2; - - for (int j=0; j<maxnoofULTunnels; j++) { - /* DLTunnels_Modified_Item */ - asn1cSequenceAdd(drbs_modified_item->dLUPTNLInformation_ToBeSetup_List.list, - F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); - asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item, tmp); - tmp->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, gTPTunnel); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); - OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", strlen("1204")); + if(resp->drbs_to_be_modified_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie6); + ie6->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_List; + ie6->criticality = F1AP_Criticality_ignore; + ie6->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_Modified_List; + + for (int i=0; i<resp->drbs_to_be_modified_length; i++) { + asn1cSequenceAdd(ie6->value.choice.DRBs_Modified_List.list, + F1AP_DRBs_Modified_ItemIEs_t, drbs_modified_item_ies); + drbs_modified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_Item; + drbs_modified_item_ies->criticality = F1AP_Criticality_ignore; + drbs_modified_item_ies->value.present = F1AP_DRBs_Modified_ItemIEs__value_PR_DRBs_Modified_Item; + /* DRBs_modified_Item */ + F1AP_DRBs_Modified_Item_t *drbs_modified_item= &drbs_modified_item_ies->value.choice.DRBs_Modified_Item; + /* dRBID */ + drbs_modified_item->dRBID = resp->drbs_to_be_modified[i].drb_id; + + /* ULTunnels_Modified_List */ + for (int j=0; j<resp->drbs_to_be_modified[i].up_dl_tnl_length; j++) { + /* DLTunnels_Modified_Item */ + asn1cSequenceAdd(drbs_modified_item->dLUPTNLInformation_ToBeSetup_List.list, + F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); + asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item, tmp); + tmp->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; + asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, gTPTunnel); + /* transportLayerAddress */ + struct sockaddr_in addr= {0}; + inet_pton(AF_INET, getCxt(false,instance)->setupReq.DU_f1_ip_address.ipv4_address, + &addr.sin_addr.s_addr); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress); + /* gTP_TEID */ + INT32_TO_OCTET_STRING(resp->drbs_to_be_modified[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + } } } - /* mandatory */ + /* optional */ /* c7. SRBs_FailedToBeSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie7); - ie7->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List; - ie7->criticality = F1AP_Criticality_reject; - ie7->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SRBs_FailedToBeSetupMod_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie7->value.choice.SRBs_FailedToBeSetupMod_List.list, - F1AP_SRBs_FailedToBeSetupMod_ItemIEs_t, srbs_failedToBeSetupMod_item_ies); - srbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_Item; - srbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; - srbs_failedToBeSetupMod_item_ies->value.present = F1AP_SRBs_FailedToBeSetupMod_ItemIEs__value_PR_SRBs_FailedToBeSetupMod_Item; - /* 9.1 SRBs_FailedToBeSetupMod_Item */ - F1AP_SRBs_FailedToBeSetupMod_Item_t *srbs_failedToBeSetupMod_item= - &srbs_failedToBeSetupMod_item_ies->value.choice.SRBs_FailedToBeSetupMod_Item; - /* - sRBID */ - srbs_failedToBeSetupMod_item->sRBID = 50L; - asn1cCalloc(srbs_failedToBeSetupMod_item->cause, tmp) - tmp->present = F1AP_Cause_PR_radioNetwork; - tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + if(resp->srbs_failed_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie7); + ie7->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List; + ie7->criticality = F1AP_Criticality_reject; + ie7->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SRBs_FailedToBeSetupMod_List; + + for (int i=0; i<resp->srbs_to_be_setup_length; i++) { + asn1cSequenceAdd(ie7->value.choice.SRBs_FailedToBeSetupMod_List.list, + F1AP_SRBs_FailedToBeSetupMod_ItemIEs_t, srbs_failedToBeSetupMod_item_ies); + srbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_Item; + srbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; + srbs_failedToBeSetupMod_item_ies->value.present = F1AP_SRBs_FailedToBeSetupMod_ItemIEs__value_PR_SRBs_FailedToBeSetupMod_Item; + /* 9.1 SRBs_FailedToBeSetupMod_Item */ + F1AP_SRBs_FailedToBeSetupMod_Item_t *srbs_failedToBeSetupMod_item= + &srbs_failedToBeSetupMod_item_ies->value.choice.SRBs_FailedToBeSetupMod_Item; + /* - sRBID */ + srbs_failedToBeSetupMod_item->sRBID = resp->srbs_failed_to_be_setup[i].rb_id; + asn1cCalloc(srbs_failedToBeSetupMod_item->cause, tmp) + tmp->present = F1AP_Cause_PR_radioNetwork; + tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + } } - /* mandatory */ + /* optional */ /* c8. DRBs_FailedToBeSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie8); - ie8->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List; - ie8->criticality = F1AP_Criticality_reject; - ie8->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeSetupMod_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie8->value.choice.DRBs_FailedToBeSetupMod_List.list, - F1AP_DRBs_FailedToBeSetupMod_ItemIEs_t, drbs_failedToBeSetupMod_item_ies); - drbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_Item; - drbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; - drbs_failedToBeSetupMod_item_ies->value.present = F1AP_DRBs_FailedToBeSetupMod_ItemIEs__value_PR_DRBs_FailedToBeSetupMod_Item; - /* 10.1 DRBs_ToBeSetupMod_Item */ - F1AP_DRBs_FailedToBeSetupMod_Item_t *drbs_failedToBeSetupMod_item= - &drbs_failedToBeSetupMod_item_ies->value.choice.DRBs_FailedToBeSetupMod_Item; - /* dRBID */ - drbs_failedToBeSetupMod_item->dRBID = 30L; - drbs_failedToBeSetupMod_item->cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t)); - drbs_failedToBeSetupMod_item->cause->present = F1AP_Cause_PR_radioNetwork; - drbs_failedToBeSetupMod_item->cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + if(resp->drbs_failed_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie8); + ie8->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List; + ie8->criticality = F1AP_Criticality_reject; + ie8->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeSetupMod_List; + + for (int i=0; i<resp->drbs_failed_to_be_setup_length; i++) { + asn1cSequenceAdd(ie8->value.choice.DRBs_FailedToBeSetupMod_List.list, + F1AP_DRBs_FailedToBeSetupMod_ItemIEs_t, drbs_failedToBeSetupMod_item_ies); + drbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_Item; + drbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; + drbs_failedToBeSetupMod_item_ies->value.present = F1AP_DRBs_FailedToBeSetupMod_ItemIEs__value_PR_DRBs_FailedToBeSetupMod_Item; + /* DRBs_FailedToBeSetupMod_Item */ + F1AP_DRBs_FailedToBeSetupMod_Item_t *drbs_failedToBeSetupMod_item= + &drbs_failedToBeSetupMod_item_ies->value.choice.DRBs_FailedToBeSetupMod_Item; + /* dRBID */ + drbs_failedToBeSetupMod_item->dRBID = resp->drbs_failed_to_be_setup[i].rb_id; + drbs_failedToBeSetupMod_item->cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t)); + drbs_failedToBeSetupMod_item->cause->present = F1AP_Cause_PR_radioNetwork; + drbs_failedToBeSetupMod_item->cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + } } - /* mandatory */ + /* optional */ /* c9. SCell_FailedtoSetupMod_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie9); - ie9->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List; - ie9->criticality = F1AP_Criticality_ignore; - ie9->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SCell_FailedtoSetupMod_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie9->value.choice.SCell_FailedtoSetupMod_List.list, - F1AP_SCell_FailedtoSetupMod_ItemIEs_t, scell_failedtoSetupMod_item_ies); - scell_failedtoSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_Item; - scell_failedtoSetupMod_item_ies->criticality = F1AP_Criticality_ignore; - scell_failedtoSetupMod_item_ies->value.present = F1AP_SCell_FailedtoSetupMod_ItemIEs__value_PR_SCell_FailedtoSetupMod_Item; - /* 8.1 SCell_ToBeSetup_Item */ - F1AP_SCell_FailedtoSetupMod_Item_t *scell_failedtoSetupMod_item=&scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item; - /* - sCell_ID */ - addnRCGI(scell_failedtoSetupMod_item->sCell_ID, &f1ap_req(false, instance)->cell[i]); - asn1cCalloc(scell_failedtoSetupMod_item->cause, tmp); - tmp->present = F1AP_Cause_PR_radioNetwork; - tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + if(0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie9); + ie9->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List; + ie9->criticality = F1AP_Criticality_ignore; + ie9->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SCell_FailedtoSetupMod_List; + + for (int i=0; i<1; i++) { + asn1cSequenceAdd(ie9->value.choice.SCell_FailedtoSetupMod_List.list, + F1AP_SCell_FailedtoSetupMod_ItemIEs_t, scell_failedtoSetupMod_item_ies); + scell_failedtoSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_Item; + scell_failedtoSetupMod_item_ies->criticality = F1AP_Criticality_ignore; + scell_failedtoSetupMod_item_ies->value.present = F1AP_SCell_FailedtoSetupMod_ItemIEs__value_PR_SCell_FailedtoSetupMod_Item; + /* 8.1 SCell_ToBeSetup_Item */ + F1AP_SCell_FailedtoSetupMod_Item_t *scell_failedtoSetupMod_item=&scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item; + /* - sCell_ID */ + addnRCGI(scell_failedtoSetupMod_item->sCell_ID, &f1ap_req(false, instance)->cell[i]); + asn1cCalloc(scell_failedtoSetupMod_item->cause, tmp); + tmp->present = F1AP_Cause_PR_radioNetwork; + tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + } } - /* mandatory */ + /* optional */ /* c10. DRBs_FailedToBeModified_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie10); - ie10->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_List; - ie10->criticality = F1AP_Criticality_reject; - ie10->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeModified_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie10->value.choice.DRBs_FailedToBeModified_List.list, - F1AP_DRBs_FailedToBeModified_ItemIEs_t, drbs_failedToBeModified_item_ies); - drbs_failedToBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_Item; - drbs_failedToBeModified_item_ies->criticality = F1AP_Criticality_reject; - drbs_failedToBeModified_item_ies->value.present = F1AP_DRBs_FailedToBeModified_ItemIEs__value_PR_DRBs_FailedToBeModified_Item; - /* 13.1 DRBs_FailedToBeModified_Item */ - F1AP_DRBs_FailedToBeModified_Item_t *drbs_failedToBeModified_item= - &drbs_failedToBeModified_item_ies->value.choice.DRBs_FailedToBeModified_Item ; - /* dRBID */ - drbs_failedToBeModified_item->dRBID = 30L; - asn1cCalloc(drbs_failedToBeModified_item->cause, tmp); - tmp->present = F1AP_Cause_PR_radioNetwork; - tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + if(0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie10); + ie10->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_List; + ie10->criticality = F1AP_Criticality_reject; + ie10->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeModified_List; + + for (int i=0; i<1; i++) { + asn1cSequenceAdd(ie10->value.choice.DRBs_FailedToBeModified_List.list, + F1AP_DRBs_FailedToBeModified_ItemIEs_t, drbs_failedToBeModified_item_ies); + drbs_failedToBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_Item; + drbs_failedToBeModified_item_ies->criticality = F1AP_Criticality_reject; + drbs_failedToBeModified_item_ies->value.present = F1AP_DRBs_FailedToBeModified_ItemIEs__value_PR_DRBs_FailedToBeModified_Item; + /* 13.1 DRBs_FailedToBeModified_Item */ + F1AP_DRBs_FailedToBeModified_Item_t *drbs_failedToBeModified_item= + &drbs_failedToBeModified_item_ies->value.choice.DRBs_FailedToBeModified_Item ; + /* dRBID */ + drbs_failedToBeModified_item->dRBID = 30L; + asn1cCalloc(drbs_failedToBeModified_item->cause, tmp); + tmp->present = F1AP_Cause_PR_radioNetwork; + tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id; + } } // /* */ @@ -1162,6 +1527,28 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { } } } + /* optional */ + /* c12. SRBs_Setup_List */ + if(resp->srbs_to_be_setup_length > 0){ + asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie12); + ie12->id = F1AP_ProtocolIE_ID_id_SRBs_SetupMod_List; + ie12->criticality = F1AP_Criticality_ignore; + ie12->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SRBs_SetupMod_List; + + for (int i=0; i< resp->srbs_to_be_setup_length; i++) {// + asn1cSequenceAdd(ie12->value.choice.SRBs_SetupMod_List.list, + F1AP_SRBs_SetupMod_ItemIEs_t, srbs_setupmod_item_ies); + srbs_setupmod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_SetupMod_Item; + srbs_setupmod_item_ies->criticality = F1AP_Criticality_ignore; + srbs_setupmod_item_ies->value.present = F1AP_SRBs_SetupMod_ItemIEs__value_PR_SRBs_SetupMod_Item; + /* 11.1 SRBs_Setup_Item */ + /* ADD */ + F1AP_SRBs_SetupMod_Item_t *srbs_setupmod_item=&srbs_setupmod_item_ies->value.choice.SRBs_SetupMod_Item; + /* sRBID */ + srbs_setupmod_item->sRBID = resp->srbs_to_be_setup[i].srb_id; + srbs_setupmod_item->lCID = resp->srbs_to_be_setup[i].srb_id; + } + } /* encode */ if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { @@ -1169,9 +1556,10 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) { return -1; } - //f1ap_itti_send_sctp_data_req(false, instance, buffer, len, 0); + f1ap_itti_send_sctp_data_req(false, instance, buffer, len, getCxt(false, instance)->default_sctp_stream_id); return 0; } + int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance) { AssertFatal(1==0,"Not implemented yet\n"); } diff --git a/openair2/F1AP/f1ap_du_ue_context_management.h b/openair2/F1AP/f1ap_du_ue_context_management.h index 82643fa933ca306e73781730be184b8b7dcbd7a3..acf74f69d7216b1e77c9a9ad3868b781136ed7d5 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.h +++ b/openair2/F1AP/f1ap_du_ue_context_management.h @@ -74,7 +74,7 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, uint32_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu); -int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance); +int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, f1ap_ue_context_setup_t *resp); int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance); diff --git a/openair2/F1AP/f1ap_encoder.c b/openair2/F1AP/f1ap_encoder.c index e623e665362ec38227b55b8558d8ce9d0ec8e68e..b249f23cfece87d4af88896c0eec0544f371e6ff 100644 --- a/openair2/F1AP/f1ap_encoder.c +++ b/openair2/F1AP/f1ap_encoder.c @@ -33,7 +33,7 @@ #include "f1ap_common.h" #include "f1ap_encoder.h" -int asn1_encoder_xer_print = 1; +int asn1_encoder_xer_print = 0; int f1ap_encode_pdu(F1AP_F1AP_PDU_t *pdu, uint8_t **buffer, uint32_t *length) { ssize_t encoded; diff --git a/openair2/F1AP/f1ap_handlers.c b/openair2/F1AP/f1ap_handlers.c index fec03bb0b90002a399cdfd027fccf92acd5c0d0c..0812a976f634363b81f7368a56269540129675ab 100644 --- a/openair2/F1AP/f1ap_handlers.c +++ b/openair2/F1AP/f1ap_handlers.c @@ -50,7 +50,7 @@ f1ap_message_processing_t f1ap_messages_processing[][3] = { { DU_handle_gNB_CU_CONFIGURATION_UPDATE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE, CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE }, /* gNBCUConfigurationUpdate */ { DU_handle_UE_CONTEXT_SETUP_REQUEST, CU_handle_UE_CONTEXT_SETUP_RESPONSE, 0 }, /* UEContextSetup */ { DU_handle_UE_CONTEXT_RELEASE_COMMAND, CU_handle_UE_CONTEXT_RELEASE_COMPLETE, 0 }, /* UEContextRelease */ - { 0, 0, 0 }, /* UEContextModification */ + { DU_handle_UE_CONTEXT_MODIFICATION_REQUEST, CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE, 0 }, /* UEContextModification */ { 0, 0, 0 }, /* UEContextModificationRequired */ { 0, 0, 0 }, /* UEMobilityCommand */ { CU_handle_UE_CONTEXT_RELEASE_REQUEST, 0, 0 }, /* UEContextReleaseRequest */ diff --git a/openair2/F1AP/f1ap_itti_messaging.c b/openair2/F1AP/f1ap_itti_messaging.c index 21096a65188cb41ffb8f6946be24047b61ee5bf0..e45edcc3a3bfed2ca60d06a60e5bb39a7827333a 100644 --- a/openair2/F1AP/f1ap_itti_messaging.c +++ b/openair2/F1AP/f1ap_itti_messaging.c @@ -32,7 +32,7 @@ void f1ap_itti_send_sctp_data_req(bool isCu, instance_t instance, uint8_t *buffe sctp_data_req->buffer = buffer; sctp_data_req->buffer_length = buffer_length; sctp_data_req->stream = stream; - LOG_I(F1AP, "Sending ITTI message to SCTP Task\n"); + LOG_D(F1AP, "Sending ITTI message to SCTP Task\n"); itti_send_msg_to_task(TASK_SCTP, instance, message_p); } diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h index a7bc3e85454f200f7220c39c8e345475008c1dd0..0a50d19e139dbea8be7af77f384ff42459aa23af 100644 --- a/openair2/GNB_APP/MACRLC_nr_paramdef.h +++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h @@ -58,6 +58,7 @@ #define CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY "ulsch_max_frame_inactivity" #define CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10 "pusch_TargetSNRx10" #define CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10 "pucch_TargetSNRx10" +#define CONFIG_STRING_MACRLC_UL_PRBBLACK_SNR_THRESHOLD "ul_prbblack_SNR_threshold" #define CONFIG_STRING_MACRLC_PUCCHFAILURETHRES "pucch_FailureThres" #define CONFIG_STRING_MACRLC_PUSCHFAILURETHRES "pusch_FailureThres" #define CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER "dl_bler_target_upper" @@ -66,7 +67,8 @@ #define CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER "ul_bler_target_upper" #define CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER "ul_bler_target_lower" #define CONFIG_STRING_MACRLC_UL_MAX_MCS "ul_max_mcs" -#define CONFIG_STRING_MACRLC_HARQ_ROUND_MAX "harq_round_max" +#define CONFIG_STRING_MACRLC_DL_HARQ_ROUND_MAX "dl_harq_round_max" +#define CONFIG_STRING_MACRLC_UL_HARQ_ROUND_MAX "ul_harq_round_max" #define CONFIG_STRING_MACRLC_MIN_GRANT_PRB "min_grant_prb" #define CONFIG_STRING_MACRLC_MIN_GRANT_MCS "min_grant_mcs" @@ -96,6 +98,7 @@ {CONFIG_STRING_MACRLC_ULSCH_MAX_FRAME_INACTIVITY, NULL, 0, uptr:NULL, defintval:10, TYPE_UINT, 0}, \ {CONFIG_STRING_MACRLC_PUSCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_PUCCHTARGETSNRX10, NULL, 0, iptr:NULL, defintval:150, TYPE_INT, 0}, \ +{CONFIG_STRING_MACRLC_UL_PRBBLACK_SNR_THRESHOLD, "SNR threshold to decide whether a PRB will be blacklisted or not", 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_PUCCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_PUSCHFAILURETHRES, NULL, 0, iptr:NULL, defintval:10, TYPE_INT, 0}, \ {CONFIG_STRING_MACRLC_DL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease DL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \ @@ -104,9 +107,10 @@ {CONFIG_STRING_MACRLC_UL_BLER_TARGET_UPPER, "Upper threshold of BLER to decrease UL MCS", 0, dblptr:NULL, defdblval:0.15, TYPE_DOUBLE, 0}, \ {CONFIG_STRING_MACRLC_UL_BLER_TARGET_LOWER, "Lower threshold of BLER to increase UL MCS", 0, dblptr:NULL, defdblval:0.05, TYPE_DOUBLE, 0}, \ {CONFIG_STRING_MACRLC_UL_MAX_MCS, "Maximum UL MCS that should be used", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0}, \ -{CONFIG_STRING_MACRLC_HARQ_ROUND_MAX, "Maximum number of HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \ +{CONFIG_STRING_MACRLC_DL_HARQ_ROUND_MAX, "Maximum number of DL HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \ +{CONFIG_STRING_MACRLC_UL_HARQ_ROUND_MAX, "Maximum number of UL HARQ rounds", 0, u8ptr:NULL, defintval:4, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_MIN_GRANT_PRB, "Minimal Periodic ULSCH Grant PRBs", 0, u8ptr:NULL, defintval:5, TYPE_UINT8, 0}, \ -{CONFIG_STRING_MACRLC_MIN_GRANT_MCS, "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0} \ +{CONFIG_STRING_MACRLC_MIN_GRANT_MCS, "Minimal Periodic ULSCH Grant MCS", 0, u8ptr:NULL, defintval:9, TYPE_UINT8, 0}, \ } #define MACRLC_CC_IDX 0 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 @@ -128,17 +132,55 @@ #define MACRLC_ULSCH_MAX_FRAME_INACTIVITY 17 #define MACRLC_PUSCHTARGETSNRX10_IDX 18 #define MACRLC_PUCCHTARGETSNRX10_IDX 19 -#define MACRLC_PUCCHFAILURETHRES_IDX 20 -#define MACRLC_PUSCHFAILURETHRES_IDX 21 -#define MACRLC_DL_BLER_TARGET_UPPER_IDX 22 -#define MACRLC_DL_BLER_TARGET_LOWER_IDX 23 -#define MACRLC_DL_MAX_MCS_IDX 24 -#define MACRLC_UL_BLER_TARGET_UPPER_IDX 25 -#define MACRLC_UL_BLER_TARGET_LOWER_IDX 26 -#define MACRLC_UL_MAX_MCS_IDX 27 -#define MACRLC_HARQ_ROUND_MAX_IDX 28 -#define MACRLC_MIN_GRANT_PRB_IDX 29 -#define MACRLC_MIN_GRANT_MCS_IDX 30 +#define MACRLC_UL_PRBBLACK_SNR_THRESHOLD_IDX 20 +#define MACRLC_PUCCHFAILURETHRES_IDX 21 +#define MACRLC_PUSCHFAILURETHRES_IDX 22 +#define MACRLC_DL_BLER_TARGET_UPPER_IDX 23 +#define MACRLC_DL_BLER_TARGET_LOWER_IDX 24 +#define MACRLC_DL_MAX_MCS_IDX 25 +#define MACRLC_UL_BLER_TARGET_UPPER_IDX 26 +#define MACRLC_UL_BLER_TARGET_LOWER_IDX 27 +#define MACRLC_UL_MAX_MCS_IDX 28 +#define MACRLC_DL_HARQ_ROUND_MAX_IDX 29 +#define MACRLC_UL_HARQ_ROUND_MAX_IDX 30 +#define MACRLC_MIN_GRANT_PRB_IDX 31 +#define MACRLC_MIN_GRANT_MCS_IDX 32 + +#define MACRLCPARAMS_CHECK { \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ + { .s2 = { config_check_intrange, {1, 8} } }, /* DL max HARQ rounds */ \ + { .s2 = { config_check_intrange, {1, 8} } }, /* UL max HARQ rounds */ \ + { .s5 = { NULL } }, \ + { .s5 = { NULL } }, \ +} /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 21655a74d52e9975eb605578b9cde94309669319..f8a4e495a80f6fd8b2d606a65c61c57df2182870 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -85,7 +85,8 @@ extern uint16_t sf_ahead; int macrlc_has_f1 = 0; -extern ngran_node_t node_type; + +static ngran_node_t get_node_type(void); extern int config_check_band_frequencies(int ind, int16_t band, uint64_t downlink_frequency, int32_t uplink_frequency_offset, uint32_t frame_type); @@ -758,8 +759,6 @@ void RCconfig_NR_L1(void) { LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_nr_CC[0]=%d for init_gNB_afterRU()\n", __FUNCTION__, RC.nb_nr_CC[0]); LOG_I(PHY,"%s() NFAPI PNF mode - RC.nb_nr_macrlc_inst:%d because used by mac_top_init_gNB()\n", __FUNCTION__, RC.nb_nr_macrlc_inst); - mac_top_init_gNB(); - configure_nr_nfapi_pnf(RC.gNB[j]->eth_params_n.remote_addr, RC.gNB[j]->eth_params_n.remote_portc, RC.gNB[j]->eth_params_n.my_addr, @@ -795,6 +794,7 @@ void RCconfig_nr_macrlc() { paramdef_t GNBParams[] = GNBPARAMS_DESC; paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; + ngran_node_t node_type = get_node_type(); config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL); int num_gnbs = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt; @@ -816,18 +816,23 @@ void RCconfig_nr_macrlc() { } paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC; paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0}; + /* map parameter checking array instances to parameter definition array instances */ + checkedparam_t config_check_MacRLCParams [] = MACRLCPARAMS_CHECK; + for (int i = 0; i < sizeof(MacRLC_Params) / sizeof(paramdef_t); ++i) + MacRLC_Params[i].chkPptr = &(config_check_MacRLCParams[i]); config_getlist( &MacRLC_ParamList,MacRLC_Params,sizeof(MacRLC_Params)/sizeof(paramdef_t), NULL); if ( MacRLC_ParamList.numelt > 0) { RC.nb_nr_macrlc_inst=MacRLC_ParamList.numelt; - mac_top_init_gNB(); + mac_top_init_gNB(node_type); RC.nb_nr_mac_CC = (int*)malloc(RC.nb_nr_macrlc_inst*sizeof(int)); for (j=0;j<RC.nb_nr_macrlc_inst;j++) { RC.nb_nr_mac_CC[j] = *(MacRLC_ParamList.paramarray[j][MACRLC_CC_IDX].iptr); RC.nrmac[j]->pusch_target_snrx10 = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCHTARGETSNRX10_IDX].iptr); RC.nrmac[j]->pucch_target_snrx10 = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCHTARGETSNRX10_IDX].iptr); + RC.nrmac[j]->ul_prbblack_SNR_threshold = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_PRBBLACK_SNR_THRESHOLD_IDX].iptr); RC.nrmac[j]->pucch_failure_thres = *(MacRLC_ParamList.paramarray[j][MACRLC_PUCCHFAILURETHRES_IDX].iptr); RC.nrmac[j]->pusch_failure_thres = *(MacRLC_ParamList.paramarray[j][MACRLC_PUSCHFAILURETHRES_IDX].iptr); @@ -886,11 +891,12 @@ void RCconfig_nr_macrlc() { dl_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_UPPER_IDX].dblptr); dl_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_BLER_TARGET_LOWER_IDX].dblptr); dl_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_MAX_MCS_IDX].u8ptr); + dl_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_DL_HARQ_ROUND_MAX_IDX].u8ptr); NR_bler_options_t *ul_bler_options = &RC.nrmac[j]->ul_bler; ul_bler_options->upper = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_UPPER_IDX].dblptr); ul_bler_options->lower = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_BLER_TARGET_LOWER_IDX].dblptr); ul_bler_options->max_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_MAX_MCS_IDX].u8ptr); - RC.nrmac[j]->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_HARQ_ROUND_MAX_IDX].u8ptr); + ul_bler_options->harq_round_max = *(MacRLC_ParamList.paramarray[j][MACRLC_UL_HARQ_ROUND_MAX_IDX].u8ptr); RC.nrmac[j]->min_grant_prb = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_PRB_IDX].u8ptr); RC.nrmac[j]->min_grant_mcs = *(MacRLC_ParamList.paramarray[j][MACRLC_MIN_GRANT_MCS_IDX].u8ptr); RC.nrmac[j]->num_ulprbbl = num_prbbl; @@ -1235,8 +1241,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { (NRRRC_CONFIGURATION_REQ (msg_p).mnc_digit_length[l] == 3),"BAD MNC DIGIT LENGTH %d", NRRRC_CONFIGURATION_REQ (msg_p).mnc_digit_length[l]); } - LOG_I(GNB_APP,"SSB SCO %d\n",*GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr); - NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = *GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr; LOG_I(GNB_APP,"pdsch_AntennaPorts N1 %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr); NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts.N1 = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N1_IDX].iptr; LOG_I(GNB_APP,"pdsch_AntennaPorts N2 %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_N2_IDX].iptr); @@ -1957,9 +1961,38 @@ int RCconfig_NR_DU_F1(MessageDef *msg_p, uint32_t i) { f1Setup->measurement_timing_information[k] = "0"; f1Setup->ranac[k] = 0; f1Setup->mib[k] = rrc->carrier.MIB; - f1Setup->sib1[k] = rrc->carrier.SIB1; f1Setup->mib_length[k] = rrc->carrier.sizeof_MIB; - f1Setup->sib1_length[k] = rrc->carrier.sizeof_SIB1; + + NR_BCCH_DL_SCH_Message_t *bcch_message = NULL; + + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_BCCH_DL_SCH_Message, + (void **)&bcch_message, + (const void *)rrc->carrier.SIB1, + rrc->carrier.sizeof_SIB1); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC,"SIB1 decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_BCCH_DL_SCH_Message, bcch_message, 1 ); + exit(1); + } + + NR_SIB1_t *bcch_SIB1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; + f1Setup->sib1[k] = calloc(1,rrc->carrier.sizeof_SIB1); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_SIB1, + NULL, + (void *)bcch_SIB1, + f1Setup->sib1[k], + NR_MAX_SIB_LENGTH/8); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + + //if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + LOG_I(NR_RRC, "SIB1 container to be integrated in F1 Setup request:\n"); + xer_fprint(stdout, &asn_DEF_NR_SIB1,(void *)bcch_message->message.choice.c1->choice.systemInformationBlockType1 ); + //} + f1Setup->sib1_length[k] = (enc_rval.encoded+7)/8; break; } } @@ -2121,7 +2154,6 @@ void configure_gnb_du_mac(int inst) { // LOG_I(GNB_APP,"Configuring MAC/L1 %d, carrier->sib2 %p\n", inst, &carrier->sib2->radioResourceConfigCommon); LOG_I(GNB_APP,"Configuring gNB DU MAC/L1 %d \n", inst); rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -2227,8 +2259,8 @@ int gNB_app_handle_f1ap_gnb_cu_configuration_update(f1ap_gnb_cu_configuration_up return(ret); } -void set_node_type(void) { - int j; +static ngran_node_t get_node_type(void) +{ paramdef_t MacRLC_Params[] = MACRLCPARAMS_DESC; paramlist_def_t MacRLC_ParamList = {CONFIG_STRING_MACRLC_LIST,NULL,0}; paramdef_t GNBParams[] = GNBPARAMS_DESC; @@ -2239,24 +2271,19 @@ void set_node_type(void) { if ( MacRLC_ParamList.numelt > 0) { RC.nb_nr_macrlc_inst = MacRLC_ParamList.numelt; - for (j=0;j<RC.nb_nr_macrlc_inst;j++) { + for (int j = 0; j < RC.nb_nr_macrlc_inst; j++) { if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "f1") == 0) { macrlc_has_f1 = 1; } } } - if (strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) { - node_type = ngran_gNB_CU; - } else { - if (macrlc_has_f1 == 0) { - node_type = ngran_gNB; - LOG_I(NR_RRC,"Setting node_type to ngran_gNB\n"); - } else { - node_type = ngran_gNB_DU; - LOG_I(NR_RRC,"Setting node_type to ngran_gNB_DU\n"); - } - } + if (strcmp(*(GNBParamList.paramarray[0][GNB_TRANSPORT_S_PREFERENCE_IDX].strptr), "f1") == 0) + return ngran_gNB_CU; + else if (macrlc_has_f1 == 0) + return ngran_gNB; + else + return ngran_gNB_DU; } void nr_read_config_and_init(void) { @@ -2265,7 +2292,6 @@ void nr_read_config_and_init(void) { uint32_t gnb_nb = RC.nb_nr_inst; RCconfig_NR_L1(); - set_node_type(); RCconfig_nr_macrlc(); LOG_I(PHY, "%s() RC.nb_nr_L1_inst:%d\n", __FUNCTION__, RC.nb_nr_L1_inst); diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 52dcbd3152b1ce4c8f3401068237d29bbaf24bb6..1298434679b1e5158085b1a71e2c13fa151b7b51 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -113,7 +113,6 @@ typedef enum { #define GNB_CONFIG_STRING_REMOTE_S_PORTC "remote_s_portc" #define GNB_CONFIG_STRING_LOCAL_S_PORTD "local_s_portd" #define GNB_CONFIG_STRING_REMOTE_S_PORTD "remote_s_portd" -#define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET "ssb_SubcarrierOffset" #define GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N1 "pdsch_AntennaPorts_N1" #define GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N2 "pdsch_AntennaPorts_N2" #define GNB_CONFIG_STRING_PDSCHANTENNAPORTS_XP "pdsch_AntennaPorts_XP" @@ -149,7 +148,6 @@ typedef enum { {GNB_CONFIG_STRING_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ -{GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET, NULL, 0, iptr:NULL, defintval:31, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N1, "horiz. log. antenna ports", 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_PDSCHANTENNAPORTS_N2, "vert. log. antenna ports", 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_PDSCHANTENNAPORTS_XP, "XP log. antenna ports", 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \ @@ -160,9 +158,9 @@ typedef enum { {GNB_CONFIG_STRING_NRCELLID, NULL, 0, u64ptr:NULL, defint64val:1, TYPE_UINT64, 0}, \ {GNB_CONFIG_STRING_MINRXTXTIME, NULL, 0, iptr:NULL, defintval:2, TYPE_INT, 0}, \ {GNB_CONFIG_STRING_ULPRBBLACKLIST, NULL, 0, strptr:NULL, defstrval:"", TYPE_STRING, 0}, \ -{GNB_CONFIG_STRING_UMONDEFAULTDRB, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ +{GNB_CONFIG_STRING_UMONDEFAULTDRB, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_FORCE256QAMOFF, GNB_CONFIG_HLP_FORCE256QAMOFF, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0}, \ -{GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0} \ +{GNB_CONFIG_STRING_ENABLE_SDAP, GNB_CONFIG_HLP_STRING_ENABLE_SDAP, PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0}, \ } #define GNB_GNB_ID_IDX 0 @@ -179,20 +177,19 @@ typedef enum { #define GNB_REMOTE_S_PORTC_IDX 11 #define GNB_LOCAL_S_PORTD_IDX 12 #define GNB_REMOTE_S_PORTD_IDX 13 -#define GNB_SSB_SUBCARRIEROFFSET_IDX 14 -#define GNB_PDSCH_ANTENNAPORTS_N1_IDX 15 -#define GNB_PDSCH_ANTENNAPORTS_N2_IDX 16 -#define GNB_PDSCH_ANTENNAPORTS_XP_IDX 17 -#define GNB_PUSCH_ANTENNAPORTS_IDX 18 -#define GNB_SIB1_TDA_IDX 19 -#define GNB_DO_CSIRS_IDX 20 -#define GNB_DO_SRS_IDX 21 -#define GNB_NRCELLID_IDX 22 -#define GNB_MINRXTXTIME_IDX 23 -#define GNB_ULPRBBLACKLIST_IDX 24 -#define GNB_UMONDEFAULTDRB_IDX 25 -#define GNB_FORCE256QAMOFF_IDX 26 -#define GNB_ENABLE_SDAP_IDX 27 +#define GNB_PDSCH_ANTENNAPORTS_N1_IDX 14 +#define GNB_PDSCH_ANTENNAPORTS_N2_IDX 15 +#define GNB_PDSCH_ANTENNAPORTS_XP_IDX 16 +#define GNB_PUSCH_ANTENNAPORTS_IDX 17 +#define GNB_SIB1_TDA_IDX 18 +#define GNB_DO_CSIRS_IDX 19 +#define GNB_DO_SRS_IDX 20 +#define GNB_NRCELLID_IDX 21 +#define GNB_MINRXTXTIME_IDX 22 +#define GNB_ULPRBBLACKLIST_IDX 23 +#define GNB_UMONDEFAULTDRB_IDX 24 +#define GNB_FORCE256QAMOFF_IDX 25 +#define GNB_ENABLE_SDAP_IDX 26 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define GNBPARAMS_CHECK { \ diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index d22485d23f261823d8b028c90a46b056273eb9eb..52a9048cd07624006261e4fc9118207b2778160c 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -1104,7 +1104,7 @@ void eNB_Config_Local_DRX(instance_t Mod_id, /* Get struct to modify */ UE_scheduling_control = &(UE_info_mac->UE_sched_ctrl[UE_id]); - UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when no error + UE_scheduling_control->cdrx_configured = false; // will be set to true when no error /* Check drx_Configuration */ if (drx_Configuration == NULL) { @@ -1119,9 +1119,9 @@ void eNB_Config_Local_DRX(instance_t Mod_id, } /* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */ - UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when receiving RRC Reconfiguration Complete - UE_scheduling_control->cdrx_waiting_ack = TRUE; // waiting for RRC Reconfiguration Complete message - UE_scheduling_control->in_active_time = FALSE; + UE_scheduling_control->cdrx_configured = false; // will be set to true when receiving RRC Reconfiguration Complete + UE_scheduling_control->cdrx_waiting_ack = true; // waiting for RRC Reconfiguration Complete message + UE_scheduling_control->in_active_time = false; UE_scheduling_control->dci0_ongoing_timer = 0; UE_scheduling_control->on_duration_timer = 0; struct LTE_DRX_Config__setup *choiceSetup = &drx_Configuration->choice.setup; @@ -1297,13 +1297,13 @@ void eNB_Config_Local_DRX(instance_t Mod_id, } if (choiceSetup->shortDRX == NULL) { - UE_scheduling_control->in_short_drx_cycle = FALSE; + UE_scheduling_control->in_short_drx_cycle = false; UE_scheduling_control->drx_shortCycle_timer_value = 0; UE_scheduling_control->short_drx_cycle_duration = 0; UE_scheduling_control->drx_shortCycle_timer = 0; UE_scheduling_control->drx_shortCycle_timer_thres = -1; } else { - UE_scheduling_control->in_short_drx_cycle = FALSE; + UE_scheduling_control->in_short_drx_cycle = false; UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) choiceSetup->shortDRX->drxShortCycleTimer; switch (choiceSetup->shortDRX->shortDRX_Cycle) { @@ -1380,7 +1380,7 @@ void eNB_Config_Local_DRX(instance_t Mod_id, UE_scheduling_control->drx_shortCycle_timer_thres = UE_scheduling_control->drx_shortCycle_timer_value * UE_scheduling_control->short_drx_cycle_duration; } - UE_scheduling_control->in_long_drx_cycle = FALSE; + UE_scheduling_control->in_long_drx_cycle = false; UE_scheduling_control->drx_longCycle_timer = 0; switch (choiceSetup->longDRX_CycleStartOffset.present) { diff --git a/openair2/LAYER2/MAC/defs_NB_IoT.h b/openair2/LAYER2/MAC/defs_NB_IoT.h index d4945f0182d5b3ddfd0bbb81b554a27b59d75b20..abe780741c05c225f30758cfc5b622644e6da58d 100644 --- a/openair2/LAYER2/MAC/defs_NB_IoT.h +++ b/openair2/LAYER2/MAC/defs_NB_IoT.h @@ -243,7 +243,6 @@ typedef struct { // -1:No UE in list int tail; int num_UEs; - //boolean_t active[MAX_MAX_MOBILES_PER_ENB_NB_IoT]; } UE_list_NB_IoT_t; @@ -403,7 +402,7 @@ typedef struct schedule_result{ // pointer to DCI void *DCI_pdu; // when all the procedure related to this DCI, enable this flag - boolean_t DCI_release; + bool DCI_release; // Indicate the channel which to transmit channel_NB_IoT_t channel; // rnti @@ -452,7 +451,7 @@ typedef enum ce_level_e{ /*! \brief eNB template for the Random access information */ typedef struct RA_TEMPLATE_NB_IoT_s{ - boolean_t active; + bool active; uint32_t msg3_retransmit_count; uint32_t msg4_retransmit_count; uint16_t ta; @@ -461,8 +460,8 @@ typedef struct RA_TEMPLATE_NB_IoT_s{ rnti_t ue_rnti; rnti_t ra_rnti; struct RA_TEMPLATE_NB_IoT_s *next, *prev; - boolean_t wait_msg4_ack; - boolean_t wait_msg3_ack; + bool wait_msg4_ack; + bool wait_msg3_ack; uint8_t rar_buffer[7]; } RA_TEMPLATE_NB_IoT; @@ -530,7 +529,7 @@ typedef struct { uint32_t pdus_in_buffer; /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */ uint32_t head_sdu_creation_time; /*!< \brief Head SDU creation time. */ uint32_t head_sdu_remaining_size_to_send; /*!< \brief remaining size of sdu: could be the total size or the remaining size of already segmented sdu */ - boolean_t head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ + bool head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ } mac_rlc_status_resp_NB_IoT_t; // global variables diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index d647eff7cbe7800c5fe49d24cca69885a9c7314a..53ab98a33fb9f87bc45429384206a4e8c03c170b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -135,7 +135,7 @@ void schedule_SRS(module_id_t module_idP, UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]); /* Test if Active Time not running since 6+ subframes */ - if (UE_scheduling_control->cdrx_configured == TRUE && UE_scheduling_control->in_active_time == FALSE) { + if (UE_scheduling_control->cdrx_configured == true && UE_scheduling_control->in_active_time == false) { /* * TODO: 6+ subframes condition not checked here */ @@ -204,7 +204,7 @@ void schedule_CSI(module_id_t module_idP, cc = &eNB->common_channels[CC_id]; for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (UE_info->active[UE_id] == FALSE) { + if (UE_info->active[UE_id] == false) { continue; } @@ -223,9 +223,9 @@ void schedule_CSI(module_id_t module_idP, */ UE_scheduling_control = &(UE_info->UE_sched_ctrl[UE_id]); - if (UE_scheduling_control->cdrx_configured == TRUE) { + if (UE_scheduling_control->cdrx_configured == true) { /* Test if CQI masking activated */ - if (UE_scheduling_control->cqi_mask_boolean == TRUE) { + if (UE_scheduling_control->cqi_mask_boolean == true) { // CQI masking => test if onDurationTime not running since 6+ subframe if (UE_scheduling_control->on_duration_timer == 0) { /* @@ -234,7 +234,7 @@ void schedule_CSI(module_id_t module_idP, continue; } } else { // No CQI masking => test if Active Time not running since 6+ subframe - if (UE_scheduling_control->in_active_time == FALSE) { + if (UE_scheduling_control->in_active_time == false) { /* * TODO: 6+ subframes condition not checked here */ @@ -677,8 +677,8 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } /* Set and increment CDRX related timers */ - if (UE_scheduling_control->cdrx_configured == TRUE) { - boolean_t harq_active_time_condition = FALSE; + if (UE_scheduling_control->cdrx_configured == true) { + bool harq_active_time_condition = false; UE_TEMPLATE *UE_template = NULL; unsigned long active_time_condition = 0; // variable used only for tracing purpose @@ -721,7 +721,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id]++; if (UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id] > 5) { - harq_active_time_condition = TRUE; + harq_active_time_condition = true; UE_scheduling_control->ul_synchronous_harq_timer[CC_id][harq_process_id] = 0; active_time_condition = 5; // for tracing purpose } @@ -747,24 +747,24 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, /* When timer expires switch into short or long DRX cycle */ if (UE_scheduling_control->drx_shortCycle_timer_thres > 0) { - UE_scheduling_control->in_short_drx_cycle = TRUE; + UE_scheduling_control->in_short_drx_cycle = true; UE_scheduling_control->drx_shortCycle_timer = 0; - UE_scheduling_control->in_long_drx_cycle = FALSE; + UE_scheduling_control->in_long_drx_cycle = false; } else { - UE_scheduling_control->in_long_drx_cycle = TRUE; + UE_scheduling_control->in_long_drx_cycle = true; } } } /* Short DRX Cycle */ - if (UE_scheduling_control->in_short_drx_cycle == TRUE) { + if (UE_scheduling_control->in_short_drx_cycle == true) { UE_scheduling_control->drx_shortCycle_timer++; /* When the Short DRX cycles are over, switch to long DRX cycle */ if (UE_scheduling_control->drx_shortCycle_timer > UE_scheduling_control->drx_shortCycle_timer_thres) { UE_scheduling_control->drx_shortCycle_timer = 0; - UE_scheduling_control->in_short_drx_cycle = FALSE; - UE_scheduling_control->in_long_drx_cycle = TRUE; + UE_scheduling_control->in_short_drx_cycle = false; + UE_scheduling_control->in_long_drx_cycle = true; UE_scheduling_control->drx_longCycle_timer = 0; } } else { @@ -772,7 +772,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } /* Long DRX Cycle */ - if (UE_scheduling_control->in_long_drx_cycle == TRUE) { + if (UE_scheduling_control->in_long_drx_cycle == true) { UE_scheduling_control->drx_longCycle_timer++; if (UE_scheduling_control->drx_longCycle_timer > UE_scheduling_control->drx_longCycle_timer_thres) { @@ -783,18 +783,18 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } /* Check for error cases */ - if ((UE_scheduling_control->in_short_drx_cycle == TRUE) && (UE_scheduling_control->in_long_drx_cycle == TRUE)) { + if ((UE_scheduling_control->in_short_drx_cycle == true) && (UE_scheduling_control->in_long_drx_cycle == true)) { LOG_E(MAC, "Error in C-DRX: UE id %d is in both short and long DRX cycle. Should not happen. Back it to long cycle only\n", UE_id); - UE_scheduling_control->in_short_drx_cycle = FALSE; + UE_scheduling_control->in_short_drx_cycle = false; } /* Condition to start On Duration Timer */ - if (UE_scheduling_control->in_short_drx_cycle == TRUE && UE_scheduling_control->on_duration_timer == 0) { + if (UE_scheduling_control->in_short_drx_cycle == true && UE_scheduling_control->on_duration_timer == 0) { if (((frameP * 10) + subframeP) % (UE_scheduling_control->short_drx_cycle_duration) == (UE_scheduling_control->drx_start_offset) % (UE_scheduling_control->short_drx_cycle_duration)) { UE_scheduling_control->on_duration_timer = 1; } - } else if (UE_scheduling_control->in_long_drx_cycle == TRUE && UE_scheduling_control->on_duration_timer == 0) { + } else if (UE_scheduling_control->in_long_drx_cycle == true && UE_scheduling_control->on_duration_timer == 0) { if (((frameP * 10) + subframeP) % (UE_scheduling_control->drx_longCycle_timer_thres) == (UE_scheduling_control->drx_start_offset)) { UE_scheduling_control->on_duration_timer = 1; @@ -811,7 +811,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, /* (a)synchronous HARQ processes handling for Active Time */ for (int harq_process_id = 0; harq_process_id < 8; harq_process_id++) { if (UE_scheduling_control->drx_retransmission_timer[harq_process_id] > 0) { - harq_active_time_condition = TRUE; + harq_active_time_condition = true; active_time_condition = 2; // for tracing purpose break; } @@ -822,9 +822,9 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, UE_scheduling_control->drx_inactivity_timer > 1 || harq_active_time_condition || UE_template->ul_SR > 0) { - UE_scheduling_control->in_active_time = TRUE; + UE_scheduling_control->in_active_time = true; } else { - UE_scheduling_control->in_active_time = FALSE; + UE_scheduling_control->in_active_time = false; } /* BEGIN VCD */ diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index e5b95a7f470db7fb9422a2543bb3b53a0c9396cf..c659df8d31a6fabdcddcd658f9c4fae85fdf5f0b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -1225,7 +1225,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:IDLE\n", module_idP, frameP, subframeP); UE_id = find_UE_id(module_idP, ra->rnti); DevAssert(UE_id != -1); - mac->UE_info.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = TRUE; + mac->UE_info.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured = true; mac->UE_info.UE_template[UE_PCCID(module_idP, UE_id)][UE_id].pusch_repetition_levels=ra->pusch_repetition_levels; cancel_ra_proc(module_idP, CC_idP, frameP, ra->rnti); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 596d978a98900184c5ea0840ba701858ae11a84e..08986221154e0bc82053d9cfe958be90778dc75e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -2075,7 +2075,7 @@ schedule_PCH(module_id_t module_idP, for (uint16_t i = 0; i < MAX_MOBILES_PER_ENB; i++) { ue_pf_po = &UE_PF_PO[CC_id][i]; - if (ue_pf_po->enable_flag != TRUE) { + if (ue_pf_po->enable_flag != true) { continue; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 6c9ffabd4f7e6b18aa173e30f040c0659d12e895..9836b643d4109b956b53fa2cc8769b11bf6afb46 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -69,7 +69,7 @@ int last_ulsch_ue_id_volte[MAX_NUM_CCs] = {-1}; uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; uint8_t dlsch_ue_select_tbl_in_use; uint8_t new_dlsch_ue_select_tbl_in_use; - boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX]; + bool pre_scd_activeUE[NUMBER_OF_UE_MAX]; eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; #endif @@ -125,7 +125,7 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, UE_info_t *UE_info = &RC.mac[module_idP]->UE_info; for (UE_id = 0; UE_id <NUMBER_OF_UE_MAX; UE_id++) { - if (pre_scd_activeUE[UE_id] != TRUE) + if (pre_scd_activeUE[UE_id] != true) continue; // store dlsch buffer @@ -210,7 +210,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( DL_req = &eNB->DL_req[CC_id].dl_config_request_body; for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { - if (UE_info->active[UE_id] == FALSE) { + if (UE_info->active[UE_id] == false) { continue; } @@ -331,7 +331,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( break; } - if (UE_info->active[UE_id] == FALSE) { + if (UE_info->active[UE_id] == false) { continue; } @@ -459,7 +459,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( break; } - if (UE_info->active[UE_id] == FALSE) { + if (UE_info->active[UE_id] == false) { continue; } @@ -607,7 +607,7 @@ static void dlsch_scheduler_pre_processor_reset_fairRR( if (rnti == NOT_A_RNTI) continue; - if (UE_info->active[UE_id] != TRUE) + if (UE_info->active[UE_id] != true) continue; LOG_D(MAC, "Running preprocessor for UE %d (%x)\n", UE_id, rnti); @@ -755,7 +755,7 @@ static void assign_rbs_required_fairRR( // clear rb allocations across all CC_id for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (UE_info->active[UE_id] != TRUE) + if (UE_info->active[UE_id] != true) continue; pCCid = UE_PCCID(Mod_id, UE_id); @@ -945,7 +945,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_info->active[i] != TRUE) + if (UE_info->active[i] != true) continue; UE_id = i; @@ -2241,7 +2241,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( // UE round >0 for ( UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++ ) { - if (UE_info->active[UE_id] == FALSE) + if (UE_info->active[UE_id] == false) continue; rnti = UE_RNTI(module_idP,UE_id); @@ -2251,7 +2251,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( CC_id = UE_PCCID(module_idP,UE_id); - if (UE_info->UE_template[CC_id][UE_id].configured == FALSE) + if (UE_info->UE_template[CC_id][UE_id].configured == false) continue; if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 0 @@ -2401,7 +2401,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( } for ( UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++ ) { - if (UE_info->active[UE_id] == FALSE) + if (UE_info->active[UE_id] == false) continue; rnti = UE_RNTI(module_idP,UE_id); @@ -2414,7 +2414,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( if (UE_id > last_ulsch_ue_id[CC_id]) continue; - if (UE_info->UE_template[CC_id][UE_id].configured == FALSE) + if (UE_info->UE_template[CC_id][UE_id].configured == false) continue; if (UE_info->UE_sched_ctrl[UE_id].ul_failure_timer > 0 diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index d53e0cadd3fa5db23506c815ef4c3bb32ed373c1..58abbd7a478010ea71fec429026637a9a0238577 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1989,7 +1989,7 @@ find_UE_id(module_id_t mod_idP, return -1; for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; UE_id++) { - if (UE_info->active[UE_id] == TRUE) { + if (UE_info->active[UE_id] == true) { int CC_id = UE_PCCID(mod_idP, UE_id); if (CC_id>=0 && CC_id<NFAPI_CC_MAX && UE_info->UE_template[CC_id][UE_id].rnti == rntiP) { return UE_id; @@ -2063,7 +2063,7 @@ UE_RNTI(module_id_t mod_idP, } //------------------------------------------------------------------------------ -boolean_t +bool is_UE_active(module_id_t mod_idP, int ue_idP) //------------------------------------------------------------------------------ @@ -2187,20 +2187,20 @@ add_new_ue(module_id_t mod_idP, UE_info->num_UEs); for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if (UE_info->active[i] == TRUE) + if (UE_info->active[i] == true) continue; UE_id = i; memset(&UE_info->UE_template[cc_idP][UE_id], 0, sizeof(UE_TEMPLATE)); UE_info->UE_template[cc_idP][UE_id].rnti = rntiP; - UE_info->UE_template[cc_idP][UE_id].configured = FALSE; + UE_info->UE_template[cc_idP][UE_id].configured = false; UE_info->numactiveCCs[UE_id] = 1; UE_info->numactiveULCCs[UE_id] = 1; UE_info->pCC_id[UE_id] = cc_idP; UE_info->ordered_CCids[0][UE_id] = cc_idP; UE_info->ordered_ULCCids[0][UE_id] = cc_idP; UE_info->num_UEs++; - UE_info->active[UE_id] = TRUE; + UE_info->active[UE_id] = true; add_ue_list(&UE_info->list, UE_id); dump_ue_list(&UE_info->list); pp_impl_param_t* dl = &RC.mac[mod_idP]->pre_processor_dl; @@ -2280,7 +2280,7 @@ rrc_mac_remove_ue(module_id_t mod_idP, UE_id, pCC_id, rntiP); - UE_info->active[UE_id] = FALSE; + UE_info->active[UE_id] = false; UE_info->num_UEs--; remove_ue_list(&UE_info->list, UE_id); @@ -2366,22 +2366,6 @@ rrc_mac_remove_ue(module_id_t mod_idP, return 0; } -//------------------------------------------------------------------------------ -/* - * Returns the previous UE_id in the scheduling list in UL or DL - */ -inline int prev(UE_list_t *listP, int nodeP) { - if (nodeP == listP->head) - return -1; /* there is no previous of the head */ - - for (int j = listP->head; j >= 0; j = listP->next[j]) - if (listP->next[j] == nodeP) - return j; - - LOG_E(MAC, "%s(): could not find previous to %d in UE_list\n", __func__, nodeP); - dump_ue_list(listP); - return -1; -} // This has to be updated to include BSR information //------------------------------------------------------------------------------ @@ -3488,7 +3472,7 @@ has_ul_grant(module_id_t module_idP, } //------------------------------------------------------------------------------ -boolean_t +bool CCE_allocation_infeasible(int module_idP, int CC_idP, int format_flag, @@ -3501,7 +3485,7 @@ CCE_allocation_infeasible(int module_idP, nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu]; nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe].hi_dci0_request_body; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi]; - boolean_t res = TRUE; + bool res = true; if (format_flag != 2) { // DL DCI if (DL_req->number_pdu == MAX_NUM_DL_PDU) { @@ -3517,7 +3501,7 @@ CCE_allocation_infeasible(int module_idP, subframe, format_flag, rnti, aggregation); if (allocate_CCEs(module_idP, CC_idP, 0, subframe, 0) != -1) - res = FALSE; + res = false; DL_req->number_pdu--; } @@ -3532,7 +3516,7 @@ CCE_allocation_infeasible(int module_idP, HI_DCI0_req->number_of_dci++; if (allocate_CCEs(module_idP, CC_idP, 0, subframe, 0) != -1) - res = FALSE; + res = false; HI_DCI0_req->number_of_dci--; } @@ -5029,7 +5013,7 @@ SR_indication(module_id_t mod_idP, if (UE_id != -1) { UE_scheduling_ctrl = &(UE_info->UE_sched_ctrl[UE_id]); - if ((UE_scheduling_ctrl->cdrx_configured == TRUE) && + if ((UE_scheduling_ctrl->cdrx_configured == true) && (UE_scheduling_ctrl->dci0_ongoing_timer > 0) && (UE_scheduling_ctrl->dci0_ongoing_timer < 8)) { LOG_D(MAC, "[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d on CC_id %d. \ @@ -5052,7 +5036,7 @@ SR_indication(module_id_t mod_idP, } UE_info->UE_template[cc_idP][UE_id].ul_SR = 1; - UE_info->UE_template[cc_idP][UE_id].ul_active = TRUE; + UE_info->UE_template[cc_idP][UE_id].ul_active = true; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION, 0); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index d4f486f76162e683fd5f2c327767eddbc4e769b6..f9218d85116670ada5b0f1dfcd32cb7aeb897e04 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -242,7 +242,7 @@ rx_sdu(const module_id_t enb_mod_idP, } /* CDRX UL HARQ timers */ - if (UE_scheduling_control->cdrx_configured == TRUE) { + if (UE_scheduling_control->cdrx_configured == true) { /* Synchronous UL HARQ */ UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5; /* @@ -329,17 +329,7 @@ rx_sdu(const module_id_t enb_mod_idP, if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { // Release RNTI of LTE PHY when RA does not succeed - UE_free_list_t *free_list = NULL; - pthread_mutex_lock(&lock_ue_freelist); - free_list = &mac->UE_free_list; - free_list->UE_free_ctrl[free_list->tail_freelist].rnti = current_rnti; - free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = 1; - free_list->UE_free_ctrl[free_list->tail_freelist].raFlag = 1; - free_list->num_UEs++; - mac->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[mac->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = current_rnti; - mac->UE_release_req.ue_release_request_body.number_of_TLVs++; - free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1); - pthread_mutex_unlock(&lock_ue_freelist); + put_UE_in_freelist(enb_mod_idP, current_rnti, true); cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); nfapi_hi_dci0_request_t *hi_dci0_req = NULL; @@ -1003,7 +993,7 @@ rx_sdu(const module_id_t enb_mod_idP, /* CDRX UL HARQ timers */ if (UE_id != -1) { - if (UE_scheduling_control->cdrx_configured == TRUE) { + if (UE_scheduling_control->cdrx_configured == true) { /* Synchronous UL HARQ */ UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5; /* @@ -1447,7 +1437,7 @@ schedule_ulsch_rnti(module_id_t module_idP, continue; // don't schedule if Msg5 is not received yet - if (UE_info->UE_template[CC_id][UE_id].configured == FALSE) { + if (UE_info->UE_template[CC_id][UE_id].configured == false) { LOG_D(MAC, "[eNB %d] frame %d, subframe %d, UE %d: not configured, skipping " "UE scheduling \n", @@ -2033,7 +2023,7 @@ void schedule_ulsch_rnti_emtc(module_id_t module_idP, } /* Don't schedule if Msg4 is not received yet */ - if (UE_template->configured == FALSE) { + if (UE_template->configured == false) { LOG_D(MAC,"[eNB %d] frame %d subframe %d, UE %d: not configured, skipping UE scheduling \n", module_idP, frameP, diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 6637d05a8afacc5f18e117058d36e0936f2f4b2a..1fd7182c6f9d5ab0b4affc4eb50a71cea2044ceb 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -811,9 +811,9 @@ typedef struct { /// TBS from last UL scheduling int TBS_UL[8]; /// Flag to indicate UL has been scheduled at least once - boolean_t ul_active; + bool ul_active; /// Flag to indicate UE has been configured (ACK from RRCConnectionSetup received) - boolean_t configured; + bool configured; /// MCS from last scheduling uint8_t mcs[8]; @@ -1026,16 +1026,16 @@ typedef struct { /* C-DRX related timers */ /* Note: only valid for FDD and LTE UE when this comment is written (11-01-19)*/ - /// is TRUE if the cqi mask feature is activated by RRC configuration - boolean_t cqi_mask_boolean; - /// is TRUE if the following drx parameters are configured for UE - boolean_t cdrx_configured; + /// is true if the cqi mask feature is activated by RRC configuration + bool cqi_mask_boolean; + /// is true if the following drx parameters are configured for UE + bool cdrx_configured; /* - * if TRUE, the eNB has configured the CDRX locally, but is waiting for the UE to acknowledge + * if true, the eNB has configured the CDRX locally, but is waiting for the UE to acknowledge * the activation. This is needed, during the RRC configuration process, when the context is * configured on the eNB side, but not yet on the UE side... */ - boolean_t cdrx_waiting_ack; + bool cdrx_waiting_ack; /* * Is set when a ULSCH scheduling is done and run until the first corresponding transmission is done (4 subframes). * When set, SR cannot be set for the UE. This allows OAI to avoid concidering a SR as uncompleted if the UE sends @@ -1043,16 +1043,16 @@ typedef struct { * create a lost in timers synchronization. */ uint8_t dci0_ongoing_timer; - /// is TRUE if the UE is in "Active Time", hence listening to PDCCH - boolean_t in_active_time; + /// is true if the UE is in "Active Time", hence listening to PDCCH + bool in_active_time; /// OnDurationTimer uint16_t on_duration_timer; uint16_t on_duration_timer_thres; /// drx-InactivityTimer uint16_t drx_inactivity_timer; uint16_t drx_inactivity_timer_thres; - /// is TRUE if UE is currently in short DRX cycle - boolean_t in_short_drx_cycle; + /// is true if UE is currently in short DRX cycle + bool in_short_drx_cycle; /// drxShortCycleTimer int (1..16) (number of short DRX cycles duration before long DRX cycles) uint8_t drx_shortCycle_timer_value; /// shortDRX-Cycle (duration of one short DRX cycle) @@ -1060,8 +1060,8 @@ typedef struct { /// DRX short cycle timer before switching to long DRX cycle = drx_shortCycle_timer_value * short_drx_cycle_duration uint16_t drx_shortCycle_timer; uint16_t drx_shortCycle_timer_thres; - /// is TRUE if UE is currently in long DRX cycle - boolean_t in_long_drx_cycle; + /// is true if UE is currently in long DRX cycle + bool in_long_drx_cycle; /// longDRX-CycleStartOffset (long DRX cycle timer) uint16_t drx_longCycle_timer; uint16_t drx_longCycle_timer_thres; @@ -1183,7 +1183,7 @@ typedef struct { UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_ENB]; UE_list_t list; int num_UEs; - boolean_t active[MAX_MOBILES_PER_ENB]; + bool active[MAX_MOBILES_PER_ENB]; } UE_info_t; /*! \brief deleting control information*/ @@ -1191,18 +1191,10 @@ typedef struct { ///rnti of UE rnti_t rnti; ///remove UE context flag - boolean_t removeContextFlg; + bool removeContextFlg; ///remove RA flag - boolean_t raFlag; + bool raFlag; } UE_free_ctrl_t; -/*! \brief REMOVE UE list used by eNB to order UEs/CC for deleting*/ -typedef struct { - /// deleting control info - UE_free_ctrl_t UE_free_ctrl[NUMBER_OF_UE_MAX+1]; - int num_UEs; - int head_freelist; ///the head position of the delete list - int tail_freelist; ///the tail position of the delete list -} UE_free_list_t; /** * describes contiguous RBs @@ -1443,7 +1435,7 @@ typedef struct eNB_MAC_INST_s { /// processing time of eNB PCH scheduler time_stats_t schedule_pch; - UE_free_list_t UE_free_list; + UE_free_ctrl_t UE_free_ctrl[NUMBER_OF_UE_MAX+1]; /// for scheduling selection SCHEDULER_MODES scheduler_mode; /// Default scheduler: Pre-processor implementation. Algorithms for UL/DL diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h index 522dc2721ff0674ba4cb4d29a431a43f7f40458d..212422898be33c72f7cf149e5259ef5f12cad99d 100644 --- a/openair2/LAYER2/MAC/mac_extern.h +++ b/openair2/LAYER2/MAC/mac_extern.h @@ -71,7 +71,7 @@ extern rb_id_t mbms_rab_id; extern uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; extern uint8_t dlsch_ue_select_tbl_in_use; extern uint8_t new_dlsch_ue_select_tbl_in_use; -extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX]; +extern bool pre_scd_activeUE[NUMBER_OF_UE_MAX]; extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; #endif diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index b92ce85608fa726952fad9574589ac1ef3dde6e1..889c727fdd5a98ca560e52ff01180e17720e5fb0 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -400,7 +400,7 @@ int find_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP); rnti_t UE_RNTI(module_id_t module_idP, int UE_id); int UE_PCCID(module_id_t module_idP, int UE_id); uint8_t find_active_UEs(module_id_t module_idP); -boolean_t is_UE_active(module_id_t module_idP, int UE_id); +bool is_UE_active(module_id_t module_idP, int UE_id); uint8_t get_aggregation(uint8_t bw_index, uint8_t cqi, uint8_t dci_fmt); int8_t find_active_UEs_with_traffic(module_id_t module_idP); @@ -416,11 +416,11 @@ int get_nCCE_offset(int *CCE_table, int allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t subframeP, int test_only); -boolean_t CCE_allocation_infeasible(int module_idP, - int CC_idP, - int common_flag, - int subframe, - int aggregation, int rnti); +bool CCE_allocation_infeasible(int module_idP, + int CC_idP, + int common_flag, + int subframe, + int aggregation, int rnti); /* tries to allocate a CCE. If it succeeds, reserves NFAPI DCI and DLSCH config */ int CCE_try_allocate_dlsch(int module_id, int CC_id, @@ -741,13 +741,12 @@ BSR_SHORT *get_bsr_short(module_id_t module_idP, uint8_t bsr_len); */ BSR_LONG *get_bsr_long(module_id_t module_idP, uint8_t bsr_len); -/*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP,sub_frame_t subframeP) +/*! \fn bool update_bsr(module_id_t module_idP, frame_t frameP,sub_frame_t subframeP) \brief get the rlc stats and update the bsr level for each lcid \param[in] Mod_id instance of the UE \param[in] frame Frame index */ -boolean_t update_bsr(module_id_t module_idP, frame_t frameP, - sub_frame_t subframeP, eNB_index_t eNB_index); +bool update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, eNB_index_t eNB_index); /*! \fn locate_BsrIndexByBufferSize (int *table, int size, int value) \brief locate the BSR level in the table as defined in 36.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table. diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index bb969668d6b32bf3cfdd44e9f0809bfc220bc28a..db4d51a92f8efabb3e9b102ca053a9467a3ddb9f 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -638,7 +638,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, LOG_E(MAC, "UE %d has RNTI NOT_A_RNTI!\n", UE_id); continue; } - if (UE_info->active[UE_id] != TRUE) { + if (UE_info->active[UE_id] != true) { LOG_E(MAC, "UE %d RNTI %x is NOT active!\n", UE_id, rnti); continue; } diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 926c44381cbefccd38c6a35a798c48d5dc8ac59b..d7796d1d40437c037ea218d9d4579bc5bb1f812d 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -2325,8 +2325,8 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t bsr_len = 0, bsr_ce_len = 0, bsr_header_len = 0; uint8_t phr_header_len = 0, phr_ce_len = 0, phr_len = 0; uint8_t lcid = 0, lcid_rlc_pdu_count = 0; - boolean_t is_lcid_processed = FALSE; - boolean_t is_all_lcid_processed = FALSE; + bool is_lcid_processed = false; + bool is_all_lcid_processed = false; uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t sdu_lcids[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t payload_offset = 0, num_sdus = 0; @@ -2444,11 +2444,11 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, // Check for DCCH first // TO DO: Multiplex in the order defined by the logical channel prioritization for (lcid = DCCH; - (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE); lcid++) { + (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == false); lcid++) { if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) { lcid_rlc_pdu_count = 0; - is_lcid_processed = FALSE; + is_lcid_processed = false; lcid_buffer_occupancy_old = mac_rlc_get_buffer_occupancy_ind(module_idP, UE_mac_inst[module_idP]. @@ -2536,8 +2536,8 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, //No more remaining TBS after this PDU //exit the function rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - is_all_lcid_processed = TRUE; + is_lcid_processed = true; + is_all_lcid_processed = true; } else { rlc_pdu_header_len_last = (sdu_lengths[num_sdus] > 128) ? 3 : 2; @@ -2547,8 +2547,8 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total)) { rlc_pdu_header_len_last = 1; - is_lcid_processed = TRUE; - is_all_lcid_processed = TRUE; + is_lcid_processed = true; + is_all_lcid_processed = true; } } @@ -2559,7 +2559,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, lcid_rlc_pdu_count++; } else { /* avoid infinite loop ... */ - is_lcid_processed = TRUE; + is_lcid_processed = true; } /* Get updated BO after multiplexing this PDU */ @@ -3164,7 +3164,7 @@ ue_scheduler(const module_id_t module_idP, } //Check whether Regular BSR is triggered - if (update_bsr(module_idP, txFrameP, txSubframeP, eNB_indexP) == TRUE) { + if (update_bsr(module_idP, txFrameP, txSubframeP, eNB_indexP) == true) { // call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp. This should implement the procedures // outlined in Sections 5.4.4 an 5.4.5 of 36.321 UE_mac_inst[module_idP].scheduling_info.SR_pending = 1; @@ -3251,11 +3251,11 @@ ue_scheduler(const module_id_t module_idP, // to be improved -boolean_t +bool update_bsr(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, eNB_index_t eNB_index) { mac_rlc_status_resp_t rlc_status; - boolean_t bsr_regular_triggered = FALSE; + bool bsr_regular_triggered = false; uint8_t lcid; uint8_t lcgid; uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined @@ -3352,7 +3352,7 @@ update_bsr(module_id_t module_idP, frame_t frameP, (lcgid_buffer_remain [UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0)) { - bsr_regular_triggered = TRUE; + bsr_regular_triggered = true; LOG_D(MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d subframe %d\n", module_idP, lcid, @@ -3364,7 +3364,7 @@ update_bsr(module_id_t module_idP, frame_t frameP, // Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission if (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF == 0) { - bsr_regular_triggered = TRUE; + bsr_regular_triggered = true; if ((UE_mac_inst[module_idP].BSR_reporting_active & BSR_TRIGGER_REGULAR) == 0) { diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 9123afd3248bb6f750f2c43ffd66a00f9bab113b..58e435f3f15aecfefb749dd61e6455b5b95fd962 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -39,6 +39,7 @@ #include <stdbool.h> #include "NR_SubcarrierSpacing.h" +#include "NR_CSI-ReportConfig.h" #include "openair1/SCHED_NR_UE/harq_nr.h" #define NR_SHORT_BSR_TABLE_SIZE 32 @@ -63,6 +64,7 @@ #define CCCH_PAYLOAD_SIZE_MAX 512 #define RAR_PAYLOAD_SIZE_MAX 128 #define MAX_BWP_SIZE 275 +#define MAX_CSI_REPORTCONFIG 48 typedef enum frequency_range_e { FR1 = 0, @@ -512,5 +514,37 @@ typedef struct Type0_PDCCH_CSS_config_s { bool active; } NR_Type0_PDCCH_CSS_config_t; +typedef struct { + uint8_t nb_ssbri_cri; + uint8_t cri_ssbri_bitlen; + uint8_t rsrp_bitlen; + uint8_t diff_rsrp_bitlen; +} L1_RSRP_bitlen_t; + +typedef struct{ + uint8_t ri_restriction; + uint8_t cri_bitlen; + uint8_t ri_bitlen; + uint8_t li_bitlen[8]; + uint8_t pmi_x1_bitlen[8]; + uint8_t pmi_x2_bitlen[8]; + uint8_t cqi_bitlen[8]; +} CSI_Meas_bitlen_t; + +typedef struct nr_csi_report { + NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; + long periodicity; + uint16_t offset; + long ** SSB_Index_list; + long ** CSI_Index_list; +// uint8_t nb_of_nzp_csi_report; + uint8_t nb_of_csi_ssb_report; + L1_RSRP_bitlen_t CSI_report_bitlen; + CSI_Meas_bitlen_t csi_meas_bitlen; + int codebook_mode; + int N1; + int N2; +} nr_csi_report_t; + #endif /*__LAYER2_MAC_H__ */ diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 5d6f9a2f2e7263afc56e7c55eda935c22b6b1622..1855958879804ea7e88c64424d2af50c4a027b62 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -4128,22 +4128,22 @@ uint16_t compute_pucch_prb_size(uint8_t format, } } -int get_bw_tbslbrm(NR_BWP_t *genericParameters, +int get_bw_tbslbrm(int scc_bwpsize, NR_CellGroupConfig_t *cg) { - int bw = 0; - if (cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) { - struct NR_ServingCellConfig__downlinkBWP_ToAddModList *BWP_list = cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList; - for (int i=0; i<BWP_list->list.count; i++) { - genericParameters = &BWP_list->list.array[i]->bwp_Common->genericParameters; - int curr_bw = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - if (curr_bw > bw) - bw = curr_bw; + int bw = scc_bwpsize; + if (cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated) { + const NR_ServingCellConfig_t *servingCellConfig = cg->spCellConfig->spCellConfigDedicated; + if(servingCellConfig->downlinkBWP_ToAddModList) { + struct NR_ServingCellConfig__downlinkBWP_ToAddModList *BWP_list = servingCellConfig->downlinkBWP_ToAddModList; + for (int i=0; i<BWP_list->list.count; i++) { + NR_BWP_t genericParameters = BWP_list->list.array[i]->bwp_Common->genericParameters; + int curr_bw = NRRIV2BW(genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + if (curr_bw > bw) + bw = curr_bw; + } } } - else - bw = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); return bw; } @@ -4221,3 +4221,521 @@ bool set_ul_ptrs_values(NR_PTRS_UplinkConfig_t *ul_ptrs_config, } return valid; } + +//! Calculating number of bits set +uint8_t number_of_bits_set(uint8_t buf) { + uint8_t nb_of_bits_set = 0; + uint8_t mask = 0xff; + uint8_t index = 0; + + for (index=7; (buf & mask) && (index>=0) ; index--){ + if (buf & (1<<index)) + nb_of_bits_set++; + + mask>>=1; + } + return nb_of_bits_set; +} + +void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t nb_resources, + nr_csi_report_t *csi_report) { + + if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) { + if (NULL != csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS) + csi_report->CSI_report_bitlen.nb_ssbri_cri = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1; + else + /*! From Spec 38.331 + * nrofReportedRS + * The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE + * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report. + * When the field is absent the UE applies the value 1 + */ + csi_report->CSI_report_bitlen.nb_ssbri_cri= 1; + } else + csi_report->CSI_report_bitlen.nb_ssbri_cri= 2; + + if (nb_resources) { + csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_resources)); + csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP + csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP + } else { + csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0; + csi_report->CSI_report_bitlen.rsrp_bitlen = 0; + csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0; + } +} + +uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + nr_csi_report_t *csi_report) { + + struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; + uint8_t nb_allowed_ri, ri_bitlen; + uint8_t ri_restriction = 0; + + if (codebookConfig == NULL) { + csi_report->csi_meas_bitlen.ri_bitlen=0; + return ri_restriction; + } + + // codebook type1 single panel + if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present){ + struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel; + if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two){ + + ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; + + nb_allowed_ri = number_of_bits_set(ri_restriction); + ri_bitlen = ceil(log2(nb_allowed_ri)); + + ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel + csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + } + if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo){ + if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present == + NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) { + // 4 ports + + ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; + + nb_allowed_ri = number_of_bits_set(ri_restriction); + ri_bitlen = ceil(log2(nb_allowed_ri)); + + ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel + csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + } + else { + // more than 4 ports + + ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; + + nb_allowed_ri = number_of_bits_set(ri_restriction); + ri_bitlen = ceil(log2(nb_allowed_ri)); + + csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; + } + } + return ri_restriction; + } + else + AssertFatal(1==0,"Other configurations not yet implemented\n"); + return -1; +} + +void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report) { + + struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; + for(int i=0; i<8; i++) { + if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0) + csi_report->csi_meas_bitlen.li_bitlen[i]=0; + else { + // codebook type1 single panel + if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present) + csi_report->csi_meas_bitlen.li_bitlen[i]=ceil(log2(i+1))<2?ceil(log2(i+1)):2; + else + AssertFatal(1==0,"Other configurations not yet implemented\n"); + } + } +} + +void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2, + struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo) { + + // Table 5.2.2.2.1-2 in 38.214 for supported configurations + switch(morethantwo->n1_n2.present){ + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction): + *n1 = 2; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_two_TypeI_SinglePanel_Restriction): + *n1 = 2; + *n2 = 2; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction): + *n1 = 4; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_three_two_TypeI_SinglePanel_Restriction): + *n1 = 3; + *n2 = 2; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction): + *n1 = 6; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_two_TypeI_SinglePanel_Restriction): + *n1 = 4; + *n2 = 2; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_one_TypeI_SinglePanel_Restriction): + *n1 = 8; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_three_TypeI_SinglePanel_Restriction): + *n1 = 4; + *n2 = 3; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_two_TypeI_SinglePanel_Restriction): + *n1 = 4; + *n2 = 2; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_twelve_one_TypeI_SinglePanel_Restriction): + *n1 = 12; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_four_TypeI_SinglePanel_Restriction): + *n1 = 4; + *n2 = 4; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_two_TypeI_SinglePanel_Restriction): + *n1 = 8; + *n2 = 2; + *o1 = 4; + *o2 = 4; + break; + case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_sixteen_one_TypeI_SinglePanel_Restriction): + *n1 = 16; + *n2 = 1; + *o1 = 4; + *o2 = 1; + break; + default: + AssertFatal(1==0,"Not supported configuration for n1_n2 in codebook configuration"); + } +} + +void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2, + int *x1, int *x2, int rank, int codebook_mode) { + + // Table 6.3.1.1.2-1 in 38.212 + switch(rank){ + case 1: + if(n2>1) { + if (codebook_mode == 1) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 2; + } + else { + *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2)); + *x2 = 4; + } + } + else{ + if (codebook_mode == 1) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 2; + } + else { + *x1 = ceil(log2(n1*o1/2)); + *x2 = 4; + } + } + break; + case 2: + if(n1*n2 == 2) { + if (codebook_mode == 1) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 1; + } + else { + *x1 = ceil(log2(n1*o1/2)); + *x2 = 3; + } + *x1 += 1; + } + else { + if(n2>1) { + if (codebook_mode == 1) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 3; + } + else { + *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2)); + *x2 = 3; + } + } + else{ + if (codebook_mode == 1) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 1; + } + else { + *x1 = ceil(log2(n1*o1/2)); + *x2 = 3; + } + } + *x1 += 2; + } + break; + case 3: + case 4: + if(n1*n2 == 2) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 1; + } + else { + if(n1*n2 >= 8) { + *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)) + 2; + *x2 = 1; + } + else { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)) + 2; + *x2 = 1; + } + } + break; + case 5: + case 6: + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 1; + break; + case 7: + case 8: + if(n1 == 4 && n2 == 1) { + *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)); + *x2 = 1; + } + else { + if(n1 > 2 && n2 == 2) { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2/2)); + *x2 = 1; + } + else { + *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); + *x2 = 1; + } + } + break; + default: + AssertFatal(1==0,"Invalid rank in x1 x2 bit length computation\n"); + } +} + + +void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report) { + + struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; + for(int i=0; i<8; i++) { + csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=0; + csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=0; + if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0) + return; + else { + if(codebookConfig->codebookType.present == NR_CodebookConfig__codebookType_PR_type1) { + if(codebookConfig->codebookType.choice.type1->subType.present == NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel) { + if(codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present == + NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two) { + csi_report->N1 = 1; + csi_report->N2 = 1; + if (i==0) + csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=2; + if (i==1) + csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=1; + } + else { // more than two + int n1,n2,o1,o2,x1,x2; + get_n1n2_o1o2_singlepanel(&n1,&n2,&o1,&o2,codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo); + get_x1x2_bitlen_singlepanel(n1,n2,o1,o2,&x1,&x2,i+1,codebookConfig->codebookType.choice.type1->codebookMode); + csi_report->N1 = n1; + csi_report->N2 = n2; + csi_report->codebook_mode = codebookConfig->codebookType.choice.type1->codebookMode; + csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=x1; + csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=x2; + } + } + else + AssertFatal(1==0,"Type1 Multi-panel Codebook Config not yet implemented\n"); + } + else + AssertFatal(1==0,"Type2 Codebook Config not yet implemented\n"); + } + } +} + +void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report) { + + struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; + struct NR_CSI_ReportConfig__reportFreqConfiguration *freq_config = csi_reportconfig->reportFreqConfiguration; + + if (*freq_config->cqi_FormatIndicator == NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI) { + for(int i=0; i<8; i++) { + if ((ri_restriction>>i)&0x01) { + csi_report->csi_meas_bitlen.cqi_bitlen[i] = 4; + if(codebookConfig != NULL) { + if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel == codebookConfig->codebookType.choice.type1->subType.present){ + struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel; + if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo) { + if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present > + NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) { + // more than 4 antenna ports + if (i > 4) + csi_report->csi_meas_bitlen.cqi_bitlen[i] += 4; // CQI for second TB + } + } + } + } + } + else + csi_report->csi_meas_bitlen.cqi_bitlen[i] = 0; + } + } + else + AssertFatal(1==0,"Sub-band CQI reporting not yet supported"); +} + +//!TODO : same function can be written to handle csi_resources +void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template) { + uint8_t csi_report_id = 0; + uint8_t nb_resources = 0; + NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; + NR_CSI_ResourceConfigId_t csi_ResourceConfigId; + struct NR_CSI_ResourceConfig *csi_resourceconfig; + + // for each CSI measurement report configuration (list of CSI-ReportConfig) + LOG_D(NR_MAC,"Searching %d csi_reports\n",csi_MeasConfig->csi_ReportConfigToAddModList->list.count); + for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ + struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; + // MAC structure for CSI measurement reports (per UE and per report) + nr_csi_report_t *csi_report = &csi_report_template[csi_report_id]; + // csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration + // (either CSI-RS or SSB) + csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement; + // looking for CSI-ResourceConfig + int found_resource = 0; + int csi_resourceidx = 0; + while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) { + csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]; + if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) + found_resource = 1; + csi_resourceidx++; + } + AssertFatal(found_resource==1,"Not able to found any CSI-ResourceConfig with csi-ResourceConfigId %ld\n", + csi_ResourceConfigId); + + long resourceType = csi_resourceconfig->resourceType; + + reportQuantity_type = csi_reportconfig->reportQuantity.present; + csi_report->reportQuantity_type = reportQuantity_type; + + // setting the CSI or SSB index list + if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) { + for (int csi_idx = 0; csi_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_idx++) { + if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId == + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){ + //We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig + nb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count; + csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.array; + csi_report->CSI_Index_list = NULL; + break; + } + } + } + else { + if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) { + AssertFatal(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList != NULL, + "Wrong settings! Report quantity requires CSI-RS but csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList is NULL\n"); + for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) { + if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId == + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { + //For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 for spec 38.212 + nb_resources = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.count; + csi_report->CSI_Index_list = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.array; + csi_report->SSB_Index_list = NULL; + break; + } + } + } + else AssertFatal(1==0,"Only periodic resource configuration currently supported\n"); + } + LOG_D(NR_MAC,"nb_resources %d\n",nb_resources); + // computation of bit length depending on the report type + switch(reportQuantity_type){ + case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP): + compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report); + break; + case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP): + compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report); + break; + case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI): + csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); + csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); + compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + break; + case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI): + csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); + csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); + compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + break; + case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI): + csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); + csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); + compute_li_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); + break; + default: + AssertFatal(1==0,"Not yet supported CSI report quantity type"); + } + } +} + +uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id) { + + uint16_t csi_bitlen = 0; + uint16_t max_bitlen = 0; + L1_RSRP_bitlen_t *CSI_report_bitlen = NULL; + CSI_Meas_bitlen_t *csi_meas_bitlen = NULL; + + if (csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP || + csi_report_template[csi_report_id].reportQuantity_type == NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP) { + CSI_report_bitlen = &(csi_report_template[csi_report_id].CSI_report_bitlen); // This might need to be moodif for Aperiodic CSI-RS measurements + csi_bitlen += ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) + + CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen * + (CSI_report_bitlen->nb_ssbri_cri -1 ))); + } else { + csi_meas_bitlen = &(csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements + uint16_t temp_bitlen; + for (int i=0; i<8; i++) { + temp_bitlen = (csi_meas_bitlen->cri_bitlen+ + csi_meas_bitlen->ri_bitlen+ + csi_meas_bitlen->li_bitlen[i]+ + csi_meas_bitlen->cqi_bitlen[i]+ + csi_meas_bitlen->pmi_x1_bitlen[i]+ + csi_meas_bitlen->pmi_x2_bitlen[i]); + if(temp_bitlen>max_bitlen) + max_bitlen = temp_bitlen; + } + csi_bitlen += max_bitlen; + } + + return csi_bitlen; +} \ No newline at end of file diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 6caddcff78e87c71294d8f7e3e13ed6ff914cf13..3b76faeef1a8ecca1e2788104b2d1f35978fe797 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -105,7 +105,7 @@ uint8_t get_pusch_mcs_table(long *mcs_Table, uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, uint8_t nb_preambles, uint8_t unpaired, - frequency_range_t); + frequency_range_t); int ul_ant_bits(NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig,long transformPrecoder); @@ -142,7 +142,7 @@ uint32_t nr_get_code_rate_ul(uint8_t Imcs, uint8_t table_idx); uint16_t get_nr_srs_offset(NR_SRS_PeriodicityAndOffset_t periodicityAndOffset); -int get_bw_tbslbrm(NR_BWP_t *genericParameters, +int get_bw_tbslbrm(int scc_bwpsize, NR_CellGroupConfig_t *cg); uint32_t nr_compute_tbslbrm(uint16_t table, @@ -234,4 +234,36 @@ void nr_mac_gNB_rrc_ul_failure_reset(const module_id_t Mod_instP, const frame_t frameP, const sub_frame_t subframeP, const rnti_t rntiP); + +uint8_t number_of_bits_set(uint8_t buf); + +void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t nb_resources, + nr_csi_report_t *csi_report); + +uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + nr_csi_report_t *csi_report); + +void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report); + +void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2, + struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo); + +void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2, + int *x1, int *x2, int rank, int codebook_mode); + +void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report); + +void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, + uint8_t ri_restriction, + nr_csi_report_t *csi_report); + +void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, nr_csi_report_t *csi_report_template); + +uint16_t nr_get_csi_bitlen(nr_csi_report_t *csi_report_template, uint8_t csi_report_id); + #endif diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h index 4b37c19dff25bdb6208aea2233338af8f61ac2fc..7bbe8d68a751c4cb9ce36b10be00332bc53b14a3 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h @@ -74,7 +74,7 @@ extern uint8_t rb_table[34]; extern uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; extern uint8_t dlsch_ue_select_tbl_in_use; extern uint8_t new_dlsch_ue_select_tbl_in_use; -extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX]; +extern bool pre_scd_activeUE[NUMBER_OF_UE_MAX]; extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; #endif*/ diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index b0d41f317bf0d76d915a8abf57f7628d8a47e0b1..2804a9ec1e6eae746b7d530b6593b08b17f6e65b 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -190,7 +190,7 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac, cfg->ssb_table.ssb_subcarrier_offset = mac->ssb_subcarrier_offset; if (mac->frequency_range == FR1){ - cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst.inOneGroup.buf[0]<<24; + cfg->ssb_table.ssb_mask_list[0].ssb_mask = ((uint32_t) scc->ssb_PositionsInBurst.inOneGroup.buf[0]) << 24; cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0; } else{ @@ -343,7 +343,9 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); cfg->ssb_table.ssb_offset_point_a = absolute_diff/(12*scs_scaling) - 10; cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell; - cfg->ssb_table.ssb_subcarrier_offset = mac->ssb_subcarrier_offset; + + // NSA -> take ssb offset from SCS + cfg->ssb_table.ssb_subcarrier_offset = absolute_diff%(12*scs_scaling); switch (scc->ssb_PositionsInBurst->present) { case 1 : @@ -351,7 +353,7 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0; break; case 2 : - cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]<<24; + cfg->ssb_table.ssb_mask_list[0].ssb_mask = ((uint32_t) scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]) << 24; cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0; break; case 3 : @@ -578,7 +580,7 @@ int nr_rrc_mac_config_req_ue_logicalChannelBearer( int cc_idP, uint8_t gNB_index, long logicalChannelIdentity, - boolean_t status){ + bool status){ NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); mac->logicalChannelBearer_exist[logicalChannelIdentity] = status; return 0; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 800e04246456f6b81100907c7f616bc098c4b9eb..35302eaafba9562134574c3b317b22c9b3a3dc26 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -399,6 +399,11 @@ typedef struct { /// measured SSB RSRP in dBm short ssb_rsrp_dBm; + nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG]; + + /// measurements from CSI-RS + fapi_nr_csirs_measurements_t csirs_measurements; + /// Last NDI of UL HARQ processes uint8_t UL_ndi[NR_MAX_HARQ_PROCESSES]; /// first ULTX of UL HARQ processes @@ -415,7 +420,7 @@ typedef struct { uint8_t BSR_reporting_active; /// LogicalChannelConfig has bearer. - boolean_t logicalChannelBearer_exist[NR_MAX_NUM_LCID]; + bool logicalChannelBearer_exist[NR_MAX_NUM_LCID]; NR_UE_SCHEDULING_INFO scheduling_info; /// PHR @@ -546,7 +551,7 @@ typedef struct prach_association_pattern { // SSB details typedef struct ssb_info { - boolean_t transmitted; // True if the SSB index is transmitted according to the SSB positions map configuration + bool transmitted; // True if the SSB index is transmitted according to the SSB positions map configuration prach_occasion_info_t *mapped_ro[MAX_NB_RO_PER_SSB_IN_ASSOCIATION_PATTERN]; // List of mapped RACH Occasions to this SSB index uint16_t nb_mapped_ro; // Total number of mapped ROs to this SSB index } ssb_info_t; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index caa4af414456f9b1616e7d48f1cac59c3ace7bd9..161799fb6677c94a132cc6ac647683be26b0592e 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -85,14 +85,12 @@ int8_t nr_ue_decode_BCCH_DL_SCH(module_id_t module_id, \param cc_id component carrier id \param gNB_index gNB index \param long logicalChannelIdentity - \param boolean_t status*/ -int nr_rrc_mac_config_req_ue_logicalChannelBearer( - module_id_t module_id, - int cc_idP, - uint8_t gNB_index, - long logicalChannelIdentity, - boolean_t status -); + \param bool status*/ +int nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id_t module_id, + int cc_idP, + uint8_t gNB_index, + long logicalChannelIdentity, + bool status); /**\brief primitive from RRC layer to MAC layer for configuration L1/L2, now supported 4 rrc messages: MIB, cell_group_config for MAC/PHY, spcell_config(serving cell config) \param module_id module id @@ -154,14 +152,14 @@ void fill_scheduled_response(nr_scheduled_response_t *scheduled_response, */ int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slotP); -/*! \fn boolean_t update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) +/*! \fn bool update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) \brief get the rlc stats and update the bsr level for each lcid \param[in] Mod_id instance of the UE \param[in] frameP Frame index \param[in] slot slotP number \param[in] uint8_t gNB_index */ -boolean_t nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index); +bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index); /*! \fn nr_locate_BsrIndexByBufferSize (int *table, int size, int value) \brief locate the BSR level in the table as defined in 38.321. This function requires that he values in table to be monotonic, either increasing or decreasing. The returned value is not less than 0, nor greater than n-1, where n is the size of table. @@ -196,6 +194,7 @@ int nr_get_sf_retxBSRTimer(uint8_t retxBSR_Timer); int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, frame_t frame, int slot, dci_pdu_rel15_t *dci, fapi_nr_dci_indication_pdu_t *dci_ind); int nr_ue_process_dci_indication_pdu(module_id_t module_id, int cc_id, int gNB_index, frame_t frame, int slot, fapi_nr_dci_indication_pdu_t *dci); +int8_t nr_ue_process_csirs_measurements(module_id_t module_id, frame_t frame, int slot, fapi_nr_csirs_measurements_t *csirs_measurements); uint32_t get_ssb_frame(uint32_t test); @@ -215,6 +214,18 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, NR_CSI_ResourceConfigId_t csi_ResourceConfigId, NR_CSI_MeasConfig_t *csi_MeasConfig); +uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, + PUCCH_sched_t *pucch, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig); + +uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, + PUCCH_sched_t *pucch, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig); + uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, int csi_report_id, @@ -259,13 +270,6 @@ void get_bwp_info(NR_UE_MAC_INST_t *mac, NR_BWP_DownlinkCommon_t *get_bwp_downlink_common(NR_UE_MAC_INST_t *mac, NR_BWP_Id_t dl_bwp_id); -uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, - uint8_t dci_format, - uint8_t dci_length, - uint16_t rnti, - uint64_t *dci_pdu, - dci_pdu_rel15_t *nr_pdci_info_extracted); - NR_PUSCH_TimeDomainResourceAllocationList_t *choose_ul_tda_list(const NR_PUSCH_Config_t *pusch_Config,NR_PUSCH_ConfigCommon_t *pusch_ConfigCommon); NR_PDSCH_TimeDomainResourceAllocationList_t *choose_dl_tda_list(NR_PDSCH_Config_t *pdsch_Config,NR_PDSCH_ConfigCommon_t *pdsch_ConfigCommon); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h old mode 100755 new mode 100644 index 8b3f00af43d2db6988d5e717177f49438f1f15ef..3bfeb29e2e046fe5a79679f01853348ff19cf172 --- a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h +++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.h @@ -24,3 +24,4 @@ */ long nr_get_Pcmax(module_id_t mod_id); /** @}*/ + diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 735ff1bd546f8a0ed8742e1a9050c40524295ae2..507cdb2661df4f2598189be7611ab9e599e1aca0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -325,7 +325,7 @@ void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_ // ======================================= NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; - boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB + bool multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB int total_preambles_per_ssb; uint8_t ssb_nb_in_ro; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 0e043208e4fb44146a268520f4a878f07dd827c6..0d9383eaf20c36ae175700e5f0620d7742dff728 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -134,6 +134,13 @@ const initial_pucch_resource_t initial_pucch_resource[16] = { }; +static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, + uint8_t dci_format, + uint8_t dci_length, + uint16_t rnti, + uint64_t *dci_pdu, + dci_pdu_rel15_t *nr_pdci_info_extracted); + void nr_ue_init_mac(module_id_t module_idP) { int i; @@ -957,7 +964,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr if (mac->scc || mac->scc_SIB || mac->cg) { NR_BWP_t genericParameters = mac->scc ? mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters : mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters; - bw_tbslbrm = get_bw_tbslbrm(&genericParameters, mac->cg); + int BWPSize = NRRIV2BW(genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + bw_tbslbrm = get_bw_tbslbrm(BWPSize, mac->cg); } else bw_tbslbrm = dlsch_config_pdu_1_0->BWPSize; @@ -985,7 +993,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr if (dci->tpc == 3) dlsch_config_pdu_1_0->accumulated_delta_PUCCH = 3; // Sanity check for pucch_resource_indicator value received to check for false DCI. valid = 0; - if (mac->ULbwp[ul_bwp_id-1] && + if (ul_bwp_id > 0 && + mac->ULbwp[ul_bwp_id-1] && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pucch_Config->choice.setup&& @@ -1396,7 +1405,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr int nl_tbslbrm = *maxMIMO_Layers < 4 ? *maxMIMO_Layers : 4; NR_BWP_t genericParameters = mac->scc ? mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters : mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters; - int bw_tbslbrm = get_bw_tbslbrm(&genericParameters, mac->cg); + int BWPSize = NRRIV2BW(genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int bw_tbslbrm = get_bw_tbslbrm(BWPSize, mac->cg); dlsch_config_pdu_1_1->tbslbrm = nr_compute_tbslbrm(dlsch_config_pdu_1_1->mcs_table, bw_tbslbrm, nl_tbslbrm); @@ -1454,6 +1464,16 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, fr } +int8_t nr_ue_process_csirs_measurements(module_id_t module_id, + frame_t frame, + int slot, + fapi_nr_csirs_measurements_t *csirs_measurements) { + LOG_D(NR_MAC,"(%d.%d) Received CSI-RS measurements\n", frame, slot); + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + memcpy(&mac->csirs_measurements, csirs_measurements, sizeof(*csirs_measurements)); + return 0; +} + void set_harq_status(NR_UE_MAC_INST_t *mac, uint8_t pucch_id, uint8_t harq_id, @@ -1512,13 +1532,12 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, NR_BWP_UplinkCommon_t *initialUplinkBWP; if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP; - NR_BWP_Uplink_t *ubwp = mac->ULbwp[bwp_id-1]; - if (mac->cg && ubwp && + if (mac->cg && bwp_id > 1 && mac->ULbwp[bwp_id - 1] && mac->cg->spCellConfig && mac->cg->spCellConfig->spCellConfigDedicated && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { - scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + scs = mac->ULbwp[bwp_id - 1]->bwp_Common->genericParameters.subcarrierSpacing; } else scs = initialUplinkBWP->genericParameters.subcarrierSpacing; @@ -1581,7 +1600,6 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, // TODO verify if SR can be transmitted in this mode pucch_pdu->payload = (pucch->sr_payload << O_ACK) | pucch->ack_payload; - } else if (pucch->pucch_resource != NULL) { @@ -1782,8 +1800,6 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, default: AssertFatal(1==0,"Group hopping flag undefined (0,1,2) \n"); } - - } @@ -2002,7 +2018,7 @@ int find_pucch_resource_set(NR_UE_MAC_INST_t *mac, int uci_size) { * processing slots of reception/transmission * gNB_id identifier * -* RETURN : TRUE a valid resource has been found +* RETURN : true a valid resource has been found * * DESCRIPTION : return tx harq process identifier for given transmission slot * TS 38.213 9.2.1 PUCCH Resource Sets @@ -2132,7 +2148,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, int number_harq_feedback = 0; uint32_t dai_current = 0; uint32_t dai_max = 0; - bool two_transport_blocks = FALSE; + bool two_transport_blocks = false; int number_of_code_word = 1; int U_DAI_c = 0; int N_m_c_rx = 0; @@ -2154,7 +2170,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, bwpd->pdsch_Config->choice.setup && bwpd->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI && bwpd->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI[0] == 2) { - two_transport_blocks = TRUE; + two_transport_blocks = true; number_of_code_word = 2; } @@ -2178,7 +2194,8 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, sched_frame = (sched_frame + 1) % 1024; } AssertFatal(sched_slot < slots_per_frame, "sched_slot was calculated incorrect %d\n", sched_slot); - LOG_D(PHY,"HARQ pid %d is active for %d.%d (dl_slot %d, feedback_to_ul %d, is_common %d\n",dl_harq_pid, sched_frame,sched_slot,current_harq->dl_slot,current_harq->feedback_to_ul,current_harq->is_common); + LOG_D(PHY,"HARQ pid %d is active for %d.%d (dl_slot %d, feedback_to_ul %d, is_common %d\n", + dl_harq_pid, sched_frame,sched_slot,current_harq->dl_slot,current_harq->feedback_to_ul,current_harq->is_common); /* check if current tx slot should transmit downlink acknowlegment */ if (sched_frame == frame && sched_slot == slot) { if (get_softmodem_params()->emulate_l1) { @@ -2254,7 +2271,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, * For a monitoring occasion of a PDCCH with DCI format 1_0 or DCI format 1_1 in at least one serving cell, * when a UE receives a PDSCH with one transport block and the value of higher layer parameter maxNrofCodeWordsScheduledByDCI is 2, * the HARQ-ACK response is associated with the first transport block and the UE generates a NACK for the second transport block - * if spatial bundling is not applied (HARQ-ACK-spatial-bundling-PUCCH = FALSE) and generates HARQ-ACK value of ACK for the second + * if spatial bundling is not applied (HARQ-ACK-spatial-bundling-PUCCH = false) and generates HARQ-ACK value of ACK for the second * transport block if spatial bundling is applied. */ @@ -2265,7 +2282,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, ack_data[code_word][i] = 0; /* nack data transport block which has been missed */ number_harq_feedback++; } - if (two_transport_blocks == TRUE) { + if (two_transport_blocks == true) { dai_total[code_word][i] = dai[code_word][i]; /* for a single cell, dai_total is the same as dai of first cell */ } } @@ -2296,7 +2313,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, o_ACK = o_ACK | (ack_data[1][m] << O_bit_number_cw1); } - if (two_transport_blocks == TRUE) { + if (two_transport_blocks == true) { O_bit_number_cw0 = (8 * j) + 2*(V_temp - 1); } else { @@ -2311,7 +2328,7 @@ uint8_t get_downlink_ack(NR_UE_MAC_INST_t *mac, j = j + 1; } - if (two_transport_blocks == TRUE) { + if (two_transport_blocks == true) { O_ACK = 2 * ( 4 * j + V_temp2); /* for two transport blocks */ } else { @@ -2340,17 +2357,16 @@ bool trigger_periodic_scheduling_request(NR_UE_MAC_INST_t *mac, NR_BWP_Id_t bwp_id = mac->UL_BWP_Id; NR_PUCCH_Config_t *pucch_Config = NULL; int scs; - NR_BWP_Uplink_t *ubwp = mac->ULbwp[bwp_id-1]; NR_BWP_UplinkCommon_t *initialUplinkBWP; if (mac->scc) initialUplinkBWP = mac->scc->uplinkConfigCommon->initialUplinkBWP; else initialUplinkBWP = &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP; - if (mac->cg && ubwp && + if (mac->cg && bwp_id && mac->ULbwp[bwp_id - 1] && mac->cg->spCellConfig && mac->cg->spCellConfig->spCellConfigDedicated && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { - scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + scs = mac->ULbwp[bwp_id - 1]->bwp_Common->genericParameters.subcarrierSpacing; } else scs = initialUplinkBWP->genericParameters.subcarrierSpacing; @@ -2433,11 +2449,9 @@ int8_t nr_ue_get_SR(module_id_t module_idP, frame_t frameP, slot_t slot){ // start the sr-prohibittimer : rel 9 and above if (mac->scheduling_info.sr_ProhibitTimer > 0) { // timer configured mac->scheduling_info.sr_ProhibitTimer--; - mac->scheduling_info. - sr_ProhibitTimer_Running = 1; + mac->scheduling_info.sr_ProhibitTimer_Running = 1; } else { - mac->scheduling_info. - sr_ProhibitTimer_Running = 0; + mac->scheduling_info.sr_ProhibitTimer_Running = 0; } //mac->ul_active =1; return (1); //instruct phy to signal SR @@ -2560,13 +2574,17 @@ uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac, case NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP: n_csi_bits = get_ssb_rsrp_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig); break; - case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI: + n_csi_bits = get_csirs_RI_PMI_CQI_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig); + break; + case NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP: + n_csi_bits = get_csirs_RSRP_payload(mac,pucch,csi_reportconfig,csi_ResourceConfigId,csi_MeasConfig); + break; case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI: case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI: - LOG_E(NR_MAC,"Measurement report based on CSI-RS not available\n"); + LOG_E(NR_MAC,"Measurement report %d based on CSI-RS is not available\n", csi_reportconfig->reportQuantity.present); break; default: AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present); @@ -2654,6 +2672,122 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, return bits; } +uint8_t get_csirs_RI_PMI_CQI_payload(NR_UE_MAC_INST_t *mac, + PUCCH_sched_t *pucch, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig) { + + int n_bits = 0; + uint32_t temp_payload = 0; + + for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) { + + struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]; + if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) { + + for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) { + if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId == + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { + + nr_csi_report_t *csi_report = &mac->csi_report_template[csi_reportconfig->reportConfigId]; + compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template); + n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_reportconfig->reportConfigId); + + int cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen; + int ri_bitlen = csi_report->csi_meas_bitlen.ri_bitlen; + int pmi_x1_bitlen = csi_report->csi_meas_bitlen.pmi_x1_bitlen[mac->csirs_measurements.rank_indicator]; + int pmi_x2_bitlen = csi_report->csi_meas_bitlen.pmi_x2_bitlen[mac->csirs_measurements.rank_indicator]; + int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[mac->csirs_measurements.rank_indicator]; + int padding_bitlen = n_bits - (cri_bitlen + ri_bitlen + pmi_x1_bitlen + pmi_x2_bitlen + cqi_bitlen); + + // TODO: Improvements will be needed to cri_bitlen>0 and pmi_x1_bitlen>0 + temp_payload = (mac->csirs_measurements.rank_indicator<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen+padding_bitlen+pmi_x1_bitlen)) | + (mac->csirs_measurements.i1<<(cri_bitlen+cqi_bitlen+pmi_x2_bitlen)) | + (mac->csirs_measurements.i2<<(cri_bitlen+cqi_bitlen)) | + (mac->csirs_measurements.cqi<<cri_bitlen) | + 0; + + reverse_n_bits((uint8_t *)&temp_payload, n_bits); + + LOG_D(NR_MAC, "cri_bitlen = %d\n", cri_bitlen); + LOG_D(NR_MAC, "ri_bitlen = %d\n", ri_bitlen); + LOG_D(NR_MAC, "pmi_x1_bitlen = %d\n", pmi_x1_bitlen); + LOG_D(NR_MAC, "pmi_x2_bitlen = %d\n", pmi_x2_bitlen); + LOG_D(NR_MAC, "cqi_bitlen = %d\n", cqi_bitlen); + LOG_D(NR_MAC, "csi_part1_payload = 0x%x\n", temp_payload); + + LOG_D(NR_MAC, "n_bits = %d\n", n_bits); + LOG_D(NR_MAC, "csi_part1_payload = 0x%x\n", temp_payload); + + break; + } + } + } + } + pucch->csi_part1_payload = temp_payload; + return n_bits; +} + +uint8_t get_csirs_RSRP_payload(NR_UE_MAC_INST_t *mac, + PUCCH_sched_t *pucch, + struct NR_CSI_ReportConfig *csi_reportconfig, + NR_CSI_ResourceConfigId_t csi_ResourceConfigId, + NR_CSI_MeasConfig_t *csi_MeasConfig) { + + int n_bits = 0; + uint32_t temp_payload = 0; + + for (int csi_resourceidx = 0; csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count; csi_resourceidx++) { + + struct NR_CSI_ResourceConfig *csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]; + if (csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) { + + for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) { + if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId == + *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { + + nr_csi_report_t *csi_report = &mac->csi_report_template[csi_reportconfig->reportConfigId]; + compute_csi_bitlen(csi_MeasConfig, mac->csi_report_template); + n_bits = nr_get_csi_bitlen(mac->csi_report_template, csi_reportconfig->reportConfigId); + + int cri_ssbri_bitlen = csi_report->CSI_report_bitlen.cri_ssbri_bitlen; + int rsrp_bitlen = csi_report->CSI_report_bitlen.rsrp_bitlen; + int diff_rsrp_bitlen = csi_report->CSI_report_bitlen.diff_rsrp_bitlen; + + if (cri_ssbri_bitlen > 0) { + LOG_E(NR_MAC, "Implementation for cri_ssbri_bitlen>0 is not supported yet!\n");; + } + + // TODO: Improvements will be needed to cri_ssbri_bitlen>0 + // TS 38.133 - Table 10.1.6.1-1 + int rsrp_dBm = mac->csirs_measurements.rsrp_dBm; + if (rsrp_dBm < -140) { + temp_payload = 16; + } else if (rsrp_dBm > -44) { + temp_payload = 113; + } else { + temp_payload = mac->csirs_measurements.rsrp_dBm + 157; + } + + reverse_n_bits((uint8_t *)&temp_payload, n_bits); + + LOG_D(NR_MAC, "cri_ssbri_bitlen = %d\n", cri_ssbri_bitlen); + LOG_D(NR_MAC, "rsrp_bitlen = %d\n", rsrp_bitlen); + LOG_D(NR_MAC, "diff_rsrp_bitlen = %d\n", diff_rsrp_bitlen); + + LOG_D(NR_MAC, "n_bits = %d\n", n_bits); + LOG_D(NR_MAC, "csi_part1_payload = 0x%x\n", temp_payload); + + break; + } + } + } + } + + pucch->csi_part1_payload = temp_payload; + return n_bits; +} // returns index from RSRP // according to Table 10.1.6.1-1 in 38.133 @@ -2734,7 +2868,7 @@ int get_n_rb(NR_UE_MAC_INST_t *mac, int rnti_type){ } -uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, +static uint8_t nr_extract_dci_info(NR_UE_MAC_INST_t *mac, uint8_t dci_format, uint8_t dci_size, uint16_t rnti, @@ -3582,7 +3716,7 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, #endif */ - LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); + LOG_I(NR_MAC, "[%d.%d] Received TA_COMMAND %u TAGID %u CC_id %d\n", frameP, slot, ul_time_alignment->ta_command, ul_time_alignment->tag_id, CC_id); break; case DL_SCH_LCID_CON_RES_ID: diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index ad6bf3cdc4508e3f8c0c3ab99f8576b9183c7b1f..8605550593ec5adf42e3628d4ab05e7fd2496bb9 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -118,12 +118,13 @@ long get_k2(NR_UE_MAC_INST_t *mac, uint8_t time_domain_ind) { NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id; // Get K2 from RRC configuration - NR_PUSCH_Config_t *pusch_config=mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : NULL; + NR_PUSCH_Config_t *pusch_config= ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : NULL; NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; if (pusch_config && pusch_config->pusch_TimeDomainAllocationList) { pusch_TimeDomainAllocationList = pusch_config->pusch_TimeDomainAllocationList->choice.setup; } - else if (mac->ULbwp[ul_bwp_id-1] && + else if (ul_bwp_id > 0 && + mac->ULbwp[ul_bwp_id-1] && mac->ULbwp[ul_bwp_id-1]->bwp_Common&& mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon&& mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup && @@ -169,7 +170,7 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl // Calculate the index of the UL slot in mac->ul_config_request list. This is // based on the TDD pattern (slot configuration period) and number of UL+mixed // slots in the period. TS 38.213 Sec 11.1 - int mu = mac->ULbwp[ul_bwp_id-1] ? + int mu = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing : mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing; const int n = nr_slots_per_frame[mu]; @@ -205,7 +206,7 @@ void ul_layers_config(NR_UE_MAC_INST_t * mac, nfapi_nr_ue_pusch_pdu_t *pusch_con srs_config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup; } - NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[ul_bwp_id-1] ? + NR_PUSCH_Config_t *pusch_Config = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd? ubwpd->pusch_Config->choice.setup: @@ -361,7 +362,7 @@ void ul_ports_config(NR_UE_MAC_INST_t *mac, int *n_front_load_symb, nfapi_nr_ue_ mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) ubwpd = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; - NR_PUSCH_Config_t *pusch_Config = mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd?ubwpd->pusch_Config->choice.setup:NULL); + NR_PUSCH_Config_t *pusch_Config = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd?ubwpd->pusch_Config->choice.setup:NULL); AssertFatal(pusch_Config!=NULL,"pusch_Config shouldn't be null\n"); long transformPrecoder; @@ -581,7 +582,7 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, if (rar_grant) { // Note: for Msg3 or MsgA PUSCH transmission the N_PRB_oh is always set to 0 - NR_BWP_Uplink_t *ubwp = mac->ULbwp[ul_bwp_id-1]; + NR_BWP_Uplink_t *ubwp = ul_bwp_id > 0 ? mac->ULbwp[ul_bwp_id - 1] : NULL; NR_BWP_UplinkDedicated_t *ibwp; int scs,abwp_start,abwp_size,startSymbolAndLength,mappingtype; NR_PUSCH_Config_t *pusch_Config=NULL; @@ -839,11 +840,15 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, mappingtype, add_pos, dmrslength, pusch_config_pdu->start_symbol_index, mac->scc ? mac->scc->dmrs_TypeA_Position : mac->mib->dmrs_TypeA_Position); - if (mac->ULbwp[ul_bwp_id-1] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled) { - if (*dci_format != NR_UL_DCI_FORMAT_0_1) { - pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; - } - } else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || (mac->ULbwp[ul_bwp_id-1] && pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled)) { + if (ul_bwp_id > 0 && + mac->ULbwp[ul_bwp_id - 1] && + pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_disabled && + *dci_format != NR_UL_DCI_FORMAT_0_1) { + pusch_config_pdu->num_dmrs_cdm_grps_no_data = 1; + } else if (*dci_format == NR_UL_DCI_FORMAT_0_0 || + (ul_bwp_id > 0 && + mac->ULbwp[ul_bwp_id-1] && + pusch_config_pdu->transform_precoding == NR_PUSCH_Config__transformPrecoder_enabled)) { pusch_config_pdu->num_dmrs_cdm_grps_no_data = 2; } @@ -859,7 +864,8 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac, else N_PRB_oh = 0; /* PTRS */ - if (mac->ULbwp[ul_bwp_id-1] && + if (ul_bwp_id > 0 && + mac->ULbwp[ul_bwp_id-1] && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config && mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->pusch_Config->choice.setup && @@ -928,15 +934,23 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo bool srs_scheduled = false; NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + const NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id; NR_SRS_Config_t *srs_config = NULL; - if (mac->cg && - mac->cg->spCellConfig && - mac->cg->spCellConfig->spCellConfigDedicated && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { + if (ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1]) { + if (mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated && + mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->srs_Config) { + srs_config = mac->ULbwp[ul_bwp_id-1]->bwp_Dedicated->srs_Config->choice.setup; + } + } else if (mac->cg && + mac->cg->spCellConfig && + mac->cg->spCellConfig->spCellConfigDedicated && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig && + mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { srs_config = mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup; - } else { + } + + if (!srs_config) { return false; } @@ -964,7 +978,6 @@ bool nr_ue_periodic_srs_scheduling(module_id_t mod_id, frame_t frame, slot_t slo continue; } - NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id; NR_BWP_t ubwp = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters : mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters; @@ -1086,9 +1099,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in dcireq.dl_config_req = mac->dl_config_request; fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data); - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) { LOG_D(NR_MAC,"1# scheduled_response transmitted, %d, %d\n", rx_frame, rx_slot); - mac->if_module->scheduled_response(&scheduled_response); + mac->if_module->scheduled_response(&scheduled_response); + } } else { // this is for Msg2/Msg4 @@ -1247,7 +1261,7 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } //Check whether Regular BSR is triggered - if (nr_update_bsr(mod_id, txFrameP, txSlotP, gNB_indexP) == TRUE) { + if (nr_update_bsr(mod_id, txFrameP, txSlotP, gNB_indexP) == true) { // call SR procedure to generate pending SR and BSR for next PUCCH/PUSCH TxOp. This should implement the procedures // outlined in Sections 5.4.4 an 5.4.5 of 38.321 mac->scheduling_info.SR_pending = 1; @@ -1260,10 +1274,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } -boolean_t +bool nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_index) { mac_rlc_status_resp_t rlc_status; - boolean_t bsr_regular_triggered = FALSE; + bool bsr_regular_triggered = false; uint8_t lcid; uint8_t lcgid; uint8_t num_lcid_with_data = 0; // for LCID with data only if LCGID is defined @@ -1356,7 +1370,7 @@ nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_ which belong to any LCG and for which data is already available for transmission */ { - bsr_regular_triggered = TRUE; + bsr_regular_triggered = true; LOG_D(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered LCID%d LCGID%d data become available at frame %d slot %d\n", module_idP, lcid, mac->scheduling_info.LCGID[lcid], @@ -1367,7 +1381,7 @@ nr_update_bsr(module_id_t module_idP, frame_t frameP, slot_t slotP, uint8_t gNB_ // Trigger Regular BSR if ReTxBSR Timer has expired and UE has data for transmission if (mac->scheduling_info.retxBSR_SF == 0) { - bsr_regular_triggered = TRUE; + bsr_regular_triggered = true; if ((mac->BSR_reporting_active & NR_BSR_TRIGGER_REGULAR) == 0) { LOG_I(NR_MAC, "[UE %d] PDCCH Tick : MAC BSR Triggered ReTxBSR Timer expiry at frame %d slot %d\n", @@ -1557,15 +1571,14 @@ int nr_ue_pusch_scheduler(NR_UE_MAC_INST_t *mac, int delta = 0; NR_BWP_Id_t ul_bwp_id = mac->UL_BWP_Id; - NR_BWP_Uplink_t *ubwp = mac->ULbwp[ul_bwp_id-1]; // Get the numerology to calculate the Tx frame and slot - int mu = ubwp ? - ubwp->bwp_Common->genericParameters.subcarrierSpacing : + int mu = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? + mac->ULbwp[ul_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing : mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing; - NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ubwp ? - ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp_id > 0 && mac->ULbwp[ul_bwp_id-1] ? + mac->ULbwp[ul_bwp_id-1]->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; // k2 as per 3GPP TS 38.214 version 15.9.0 Release 15 ch 6.1.2.1.1 // PUSCH time domain resource allocation is higher layer configured from uschTimeDomainAllocationList in either pusch-ConfigCommon @@ -1628,7 +1641,7 @@ static void build_ro_list(NR_UE_MAC_INST_t *mac) { int y2; // PRACH Configuration Index table additional variable used to compute the valid frame numbers uint8_t slot_shift_for_map; uint8_t map_shift; - boolean_t even_slot_invalid; + bool even_slot_invalid; int64_t s_map; uint8_t prach_conf_start_symbol; // Starting symbol of the PRACH occasions in the PRACH slot uint8_t N_t_slot; // Number of PRACH occasions in a 14-symbols PRACH slot @@ -1900,7 +1913,7 @@ static void map_ssb_to_ro(NR_UE_MAC_INST_t *mac) { mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup; NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; - boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB + bool multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB uint16_t required_nb_of_prach_occasion; // Nb of RACH occasions required to map all the SSBs uint8_t required_nb_of_prach_conf_period; // Nb of PRACH configuration periods required to map all the SSBs diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 493a058e1313e73d45fec61d25e3f11c2047042b..0f4e0539f263146b009efcd361edb4d315c5426f 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -51,7 +51,6 @@ extern RAN_CONTEXT_t RC; //extern int l2_init_gNB(void); -extern void mac_top_init_gNB(void); extern uint8_t nfapi_mode; void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list, @@ -160,7 +159,7 @@ void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sche } -void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { +void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) { nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0]; RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc; @@ -335,42 +334,32 @@ void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts cfg->num_tlv++; // SSB Table Configuration - int scs_scaling = 1<<(cfg->ssb_config.scs_common.value); - if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000) - scs_scaling = scs_scaling*3; - if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666) - scs_scaling = scs_scaling>>2; uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); - uint16_t sco = absolute_diff%(12*scs_scaling); - // values of subcarrier offset larger than the limit only indicates CORESET for Type0-PDCCH CSS set is not present - int ssb_SubcarrierOffset_limit = 0; - int offset_scaling = 0; //15kHz - if(frequency_range == FR1) { - ssb_SubcarrierOffset_limit = 24; - if (ssb_SubcarrierOffset<ssb_SubcarrierOffset_limit) - offset_scaling = cfg->ssb_config.scs_common.value; - } else - ssb_SubcarrierOffset_limit = 12; - if (ssb_SubcarrierOffset<ssb_SubcarrierOffset_limit) - AssertFatal(sco==(scs_scaling * ssb_SubcarrierOffset), - "absoluteFrequencySSB has a subcarrier offset of %d while it should be %d\n",sco/scs_scaling,ssb_SubcarrierOffset); - cfg->ssb_table.ssb_offset_point_a.value = absolute_diff/(12*scs_scaling) - 10; //absoluteFrequencySSB is the central frequency of SSB which is made by 20RBs in total + const int scaling_5khz = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000 ? 3 : 1; + int sco = (absolute_diff/scaling_5khz) % 24; + if(frequency_range == FR2) + sco >>= 1; // this assumes 120kHz SCS for SSB and subCarrierSpacingCommon (only option supported by OAI for + const int scs_scaling = frequency_range == FR2 ? 1 << (*scc->ssbSubcarrierSpacing - 2) : 1 << *scc->ssbSubcarrierSpacing; + cfg->ssb_table.ssb_offset_point_a.value = absolute_diff/(12*scaling_5khz) - 10*scs_scaling; //absoluteFrequencySSB is the central frequency of SSB which is made by 20RBs in total cfg->ssb_table.ssb_offset_point_a.tl.tag = NFAPI_NR_CONFIG_SSB_OFFSET_POINT_A_TAG; cfg->num_tlv++; cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell; cfg->ssb_table.ssb_period.tl.tag = NFAPI_NR_CONFIG_SSB_PERIOD_TAG; cfg->num_tlv++; - cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset<<offset_scaling; + cfg->ssb_table.ssb_subcarrier_offset.value = sco; cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG; cfg->num_tlv++; + RC.nrmac[Mod_idP]->ssb_SubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; + RC.nrmac[Mod_idP]->ssb_OffsetPointA = cfg->ssb_table.ssb_offset_point_a.value; + switch (scc->ssb_PositionsInBurst->present) { case 1 : cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0]<<24; cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0; break; case 2 : - cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]<<24; + cfg->ssb_table.ssb_mask_list[0].ssb_mask.value = ((uint32_t) scc->ssb_PositionsInBurst->choice.mediumBitmap.buf[0]) << 24; cfg->ssb_table.ssb_mask_list[1].ssb_mask.value = 0; break; case 3 : @@ -462,8 +451,7 @@ int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_S return -1; } NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl; - const uint16_t sf_ahead = 6/(0x01<<subcarrierSpacing) + ((6%(0x01<<subcarrierSpacing))>0); - const uint16_t sl_ahead = sf_ahead * (0x01<<subcarrierSpacing); + const uint16_t sl_ahead = RC.nrmac[Mod_idP]->if_inst->sl_ahead; sched_ctrl->rrc_processing_timer = (rrc_reconfiguration_delay<<subcarrierSpacing) + sl_ahead; LOG_I(NR_MAC, "Activating RRC processing timer for UE %04x with %d ms\n", UE_info->rnti, rrc_reconfiguration_delay); @@ -471,7 +459,6 @@ int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, rnti_t rnti, NR_S } int rrc_mac_config_req_gNB(module_id_t Mod_idP, - int ssb_SubcarrierOffset, rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts, int pusch_AntennaPorts, int sib1_tda, @@ -486,19 +473,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, if (scc != NULL ) { AssertFatal((scc->ssb_PositionsInBurst->present > 0) && (scc->ssb_PositionsInBurst->present < 4), "SSB Bitmap type %d is not valid\n",scc->ssb_PositionsInBurst->present); - /* dimension UL_tti_req_ahead for number of slots in frame */ const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; - RC.nrmac[Mod_idP]->UL_tti_req_ahead[0] = calloc(n, sizeof(nfapi_nr_ul_tti_request_t)); - AssertFatal(RC.nrmac[Mod_idP]->UL_tti_req_ahead[0], - "could not allocate memory for RC.nrmac[]->UL_tti_req_ahead[]\n"); - /* fill in slot/frame numbers: slot is fixed, frame will be updated by scheduler - * consider that scheduler runs sl_ahead: the first sl_ahead slots are - * already "in the past" and thus we put frame 1 instead of 0! */ - for (int i = 0; i < n; ++i) { - nfapi_nr_ul_tti_request_t *req = &RC.nrmac[Mod_idP]->UL_tti_req_ahead[0][i]; - req->SFN = i < (RC.nrmac[Mod_idP]->if_inst->sl_ahead-1); - req->Slot = i; - } RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL = calloc(n * MAX_BWP_SIZE, sizeof(uint16_t)); AssertFatal(RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL, @@ -509,7 +484,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, int num_pdsch_antenna_ports = pdsch_AntennaPorts.N1 * pdsch_AntennaPorts.N2 * pdsch_AntennaPorts.XP; RC.nrmac[Mod_idP]->xp_pdsch_antenna_ports = pdsch_AntennaPorts.XP; config_common(Mod_idP, - ssb_SubcarrierOffset, num_pdsch_antenna_ports, pusch_AntennaPorts, scc); @@ -523,7 +497,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP, printf("Waiting for PHY_config_req\n"); } } - RC.nrmac[Mod_idP]->ssb_SubcarrierOffset = ssb_SubcarrierOffset; RC.nrmac[Mod_idP]->minRXTXTIMEpdsch = minRXTXTIMEpdsch; NR_PHY_Config_t phycfg; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 385cf5af16fe8fee26171a29008f4891b2e6090f..c87aa68f753f8b30533c148f9ad019dfd6d1d8b6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -68,6 +68,8 @@ void clear_nr_nfapi_information(gNB_MAC_INST * gNB, NR_ServingCellConfigCommon_t *scc = gNB->common_channels->ServingCellConfigCommon; const int num_slots = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + UL_tti_req_ahead_initialization(gNB, scc, num_slots, CC_idP); + nfapi_nr_dl_tti_request_t *DL_req = &gNB->DL_req[0]; nfapi_nr_dl_tti_pdcch_pdu_rel15_t **pdcch = (nfapi_nr_dl_tti_pdcch_pdu_rel15_t **)gNB->pdcch_pdu_idx[CC_idP]; nfapi_nr_ul_tti_request_t *future_ul_tti_req = diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 6daa68afed7bb7adbb1108e1bd2e63002c0e4ee2..745fc1ae2b0d7204f3fdee0ef18aafe31e3adea5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -398,7 +398,7 @@ void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, uint16_t *msg2_frame, uint16_t *msg2_slot, - NR_ServingCellConfigCommon_t *scc, + int mu, NR_ServingCellConfigCommon_t *scc, frame_type_t frame_type, uint16_t monitoring_slot_period, uint16_t monitoring_offset,uint8_t beam_index, @@ -407,10 +407,9 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, // preferentially we schedule the msg2 in the mixed slot or in the last dl slot // if they are allowed by search space configuration - uint8_t mu = *scc->ssbSubcarrierSpacing; uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow; uint8_t slot_window; - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + const int n_slots_frame = nr_slots_per_frame[mu]; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; // number of mixed slot or of last dl slot if there is no mixed slot uint8_t last_dl_slot_period = n_slots_frame-1; @@ -516,7 +515,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, int16_t timing_offset){ uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL - NR_SearchSpace_t *ss; uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset; gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; @@ -567,20 +565,8 @@ void nr_initiate_ra_proc(module_id_t module_idP, else ra_rnti = 1 + symbol + (slotP * 14) + (freq_index * 14 * 80) + (ul_carrier_id * 14 * 80 * 8); - // This should be handled differently when we use the initialBWP for RA - ra->dl_bwp_id = 0;//TODO - ra->ul_bwp_id = 0; - NR_BWP_Downlink_t *bwp=NULL; - if (ra->CellGroup && ra->CellGroup->spCellConfig && ra->CellGroup->spCellConfig->spCellConfigDedicated) { - if (ra->CellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id && - ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) { - ra->dl_bwp_id = *ra->CellGroup->spCellConfig->spCellConfigDedicated->firstActiveDownlinkBWP_Id; - bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id - 1]; - } - if (ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig && - ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id) - ra->ul_bwp_id = *ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id; - } + // Configure RA BWP + configure_UE_BWP(nr_mac, scc, NULL, ra, NULL); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); @@ -611,37 +597,6 @@ void nr_initiate_ra_proc(module_id_t module_idP, ra->timing_offset = timing_offset; ra->preamble_slot = slotP; - NR_SearchSpaceId_t ra_SearchSpace = 0; - struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = NULL; - NR_BWP_t *genericParameters = NULL; - if(bwp) { - commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - ra_SearchSpace = *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; - genericParameters = &bwp->bwp_Common->genericParameters; - } else { - commonSearchSpaceList = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - ra_SearchSpace = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; - genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - } - AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n"); - - // Common SearchSpace list - for (int i = 0; i < commonSearchSpaceList->list.count; i++) { - ss = commonSearchSpaceList->list.array[i]; - if (ss->searchSpaceId == ra_SearchSpace) - ra->ra_ss = ss; - } - - AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n"); - - ra->coreset = get_coreset(nr_mac, scc, bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common); - ra->sched_pdcch = set_pdcch_structure(nr_mac, - ra->ra_ss, - ra->coreset, - scc, - genericParameters, - &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]); - // retrieving ra pdcch monitoring period and offset find_monitoring_periodicity_offset_common(ra->ra_ss, &monitoring_slot_period, &monitoring_offset); @@ -649,6 +604,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, slotP, &msg2_frame, &msg2_slot, + ra->DL_BWP.scs, scc, frame_type, monitoring_slot_period, @@ -656,7 +612,7 @@ void nr_initiate_ra_proc(module_id_t module_idP, beam_index, cc->num_active_ssb, nr_mac->tdd_beam_association, - nr_mac->if_inst->sl_ahead); + nr_mac->if_inst->sl_ahead); ra->Msg2_frame = msg2_frame; ra->Msg2_slot = msg2_slot; @@ -738,22 +694,10 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; - NR_BWP_Uplink_t *ubwp = NULL; - NR_BWP_UplinkDedicated_t *ubwpd = NULL; - NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = NULL; - NR_BWP_t *genericParameters = NULL; - if(ra->CellGroup) { - ubwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->ul_bwp_id-1]; - ubwpd = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; - genericParameters = &ubwp->bwp_Common->genericParameters; - pusch_TimeDomainAllocationList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else { - genericParameters = &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - pusch_TimeDomainAllocationList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } - - int mu = genericParameters->subcarrierSpacing; + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList; + int mu = ul_bwp->scs; uint8_t K2 = *pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2; const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]); const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; @@ -763,7 +707,7 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t int16_t *tdd_beam_association = nr_mac->tdd_beam_association; if (*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] >= 257) { // FR2 - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + const int n_slots_frame = nr_slots_per_frame[mu]; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd,"Dynamic TDD not handled yet\n"); uint8_t tdd_period_slot = n_slots_frame/get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity); @@ -775,12 +719,11 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t tdd_beam_association[num_tdd_period] = ra->beam_id; } - int scs = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; int fh = 0; - int startSymbolAndLength = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; + int startSymbolAndLength = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; int StartSymbolIndex, NrOfSymbols; SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); - int mappingtype = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; + int mappingtype = pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; uint16_t *vrb_map_UL = &RC.nrmac[module_idP]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; @@ -821,7 +764,7 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t fill_msg3_pusch_pdu(pusch_pdu, scc, ra->msg3_round, startSymbolAndLength, - ra->rnti, scs, + ra->rnti, mu, BWPSize, BWPStart, mappingtype, fh, rbStart, ra->msg3_nb_rb); @@ -843,7 +786,7 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); pdcch_pdu_rel15 = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; ul_dci_req->numPdus += 1; - nr_configure_pdcch(pdcch_pdu_rel15, coreset, genericParameters, &ra->sched_pdcch); + nr_configure_pdcch(pdcch_pdu_rel15, coreset, false, &ra->sched_pdcch); nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; } @@ -883,26 +826,23 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t const NR_SIB1_t *sib1 = cc->sib1 ? cc->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; config_uldci(sib1, - ubwp, - ubwpd, scc, pusch_pdu, &uldci_payload, - NR_UL_DCI_FORMAT_0_0, ra->Msg3_tda_id, ra->msg3_TPC, - 0, // not used in format 0_0 - ra->ul_bwp_id); + &ra->UL_BWP); fill_dci_pdu_rel15(scc, ra->CellGroup, + &ra->DL_BWP, dci_pdu, &uldci_payload, NR_UL_DCI_FORMAT_0_0, NR_RNTI_TC, pusch_pdu->bwp_size, - ra->ul_bwp_id, - coresetid, + ul_bwp->bwp_id, + coreset, nr_mac->cset0_bwp_size); // Mark the corresponding RBs as used @@ -923,13 +863,11 @@ void nr_generate_Msg3_retransmission(module_id_t module_idP, int CC_id, frame_t ra->Msg3_slot = sched_slot; } - } void nr_get_Msg3alloc(module_id_t module_id, int CC_id, NR_ServingCellConfigCommon_t *scc, - NR_BWP_Uplink_t *ubwp, sub_frame_t current_slot, frame_t current_frame, NR_RA_t *ra, @@ -938,21 +876,18 @@ void nr_get_Msg3alloc(module_id_t module_id, // msg3 is scheduled in mixed slot in the following TDD period uint16_t msg3_nb_rb = 8; // sdu has 6 or 8 bytes - frame_type_t frame_type = RC.nrmac[module_id]->common_channels->frame_type; - int mu = ubwp ? - ubwp->bwp_Common->genericParameters.subcarrierSpacing : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; + NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; + + int mu = ul_bwp->scs; int StartSymbolIndex = 0; int NrOfSymbols = 0; int startSymbolAndLength = 0; int temp_slot = 0; ra->Msg3_tda_id = 16; // initialization to a value above limit - NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList= ubwp ? - ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList: - scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + NR_PUSCH_TimeDomainResourceAllocationList_t *pusch_TimeDomainAllocationList = ul_bwp->tdaList; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; const int n_slots_frame = nr_slots_per_frame[mu]; @@ -1016,10 +951,9 @@ void nr_get_Msg3alloc(module_id_t module_id, int bwpSize = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); int bwpStart = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - if (ra->CellGroup) { - NR_BWP_Uplink_t *ubwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->ul_bwp_id - 1]; - int act_bwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - int act_bwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + if (bwpSize != ul_bwp->BWPSize || bwpStart != ul_bwp->BWPStart) { + int act_bwp_start = ul_bwp->BWPStart; + int act_bwp_size = ul_bwp->BWPSize; if (!((bwpStart >= act_bwp_start) && ((bwpStart+bwpSize) <= (act_bwp_start+act_bwp_size)))) bwpStart = act_bwp_start; } @@ -1054,7 +988,6 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, int mappingtype, int fh, int msg3_first_rb, int msg3_nb_rb) { - int start_symbol_index,nr_of_symbols; SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols); @@ -1090,13 +1023,16 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, pusch_pdu->vrb_to_prb_mapping = 0; pusch_pdu->frequency_hopping = fh; - //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + //pusch_pdu->tx_direct_current_location; + //The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, + //which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, + //which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] pusch_pdu->uplink_frequency_shift_7p5khz = 0; //Resource Allocation in time domain pusch_pdu->start_symbol_index = start_symbol_index; pusch_pdu->nr_of_symbols = nr_of_symbols; //Optional Data only included if indicated in pduBitmap - pusch_pdu->pusch_data.rv_index = nr_rv_round_map[round]; + pusch_pdu->pusch_data.rv_index = nr_rv_round_map[round%4]; pusch_pdu->pusch_data.harq_process_id = 0; pusch_pdu->pusch_data.new_data_indicator = 1; pusch_pdu->pusch_data.num_cb = 0; @@ -1126,9 +1062,10 @@ void fill_msg3_pusch_pdu(nfapi_nr_pusch_pdu_t *pusch_pdu, void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP, NR_RA_t *ra, uint8_t *RAR_pdu) { - gNB_MAC_INST *mac = RC.nrmac[module_idP]; - NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; - NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + gNB_MAC_INST *mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_UE_UL_BWP_t *ul_bwp = &ra->UL_BWP; if (ra->state == RA_IDLE) { LOG_W(NR_MAC,"RA is not active for RA %X. skipping msg3 scheduling\n", ra->rnti); @@ -1161,20 +1098,11 @@ void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t nfapi_nr_pusch_pdu_t *pusch_pdu = &future_ul_tti_req->pdus_list[future_ul_tti_req->n_pdus].pusch_pdu; memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); - int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - int scs = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; - int fh = 0; - int startSymbolAndLength = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; - int mappingtype = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; - - if (ra->CellGroup) { - NR_BWP_Uplink_t *ubwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->ul_bwp_id - 1]; - - startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; - mappingtype = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->mappingType; - scs = ubwp->bwp_Common->genericParameters.subcarrierSpacing; - fh = ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping ? 1 : 0; - } + const int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const int scs = ul_bwp->scs; + const int fh = (ul_bwp->pusch_Config && ul_bwp->pusch_Config->frequencyHopping) ? 1 : 0; + const int startSymbolAndLength = ul_bwp->tdaList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; + const int mappingtype = ul_bwp->tdaList->list.array[ra->Msg3_tda_id]->mappingType; LOG_D(NR_MAC, "Frame %d, Slot %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", frameP, @@ -1203,6 +1131,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; + NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { @@ -1213,30 +1142,13 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_SearchSpace_t *ss = ra->ra_ss; - NR_BWP_Downlink_t *bwp = NULL; - NR_ControlResourceSet_t *coreset = NULL; - NR_BWP_t *genericParameters = NULL; - NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList=NULL; - - if (ra->CellGroup && - ra->CellGroup->spCellConfig && - ra->CellGroup->spCellConfig->spCellConfigDedicated && - ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList && - ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id-1]) { - bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id-1]; - genericParameters = &bwp->bwp_Common->genericParameters; - pdsch_TimeDomainAllocationList = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } - else { - genericParameters= &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - pdsch_TimeDomainAllocationList = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } + NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = dl_bwp->tdaList; long BWPStart = 0; long BWPSize = 0; NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL; if(*ss->controlResourceSetId!=0) { - BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + BWPStart = dl_bwp->BWPStart; BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); } else { type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; @@ -1251,7 +1163,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); AssertFatal(startSymbolIndex >= 0, "StartSymbolIndex is negative\n"); - coreset = ra->coreset; + NR_ControlResourceSet_t *coreset = ra->coreset; AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg2\n"); @@ -1303,7 +1215,6 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them - const int bwpid = bwp ? bwp->bwp_Id : 0; const int coresetid = coreset->controlResourceSetId; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid]; if (!pdcch_pdu_rel15) { @@ -1313,7 +1224,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_req->nPDUs += 1; pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nr_configure_pdcch(pdcch_pdu_rel15, coreset, genericParameters, &ra->sched_pdcch); + nr_configure_pdcch(pdcch_pdu_rel15, coreset, false, &ra->sched_pdcch); nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; } @@ -1331,37 +1242,22 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra // information to data and is reset every slot. const int pduindex = nr_mac->pdu_index[CC_id]++; - uint8_t mcsTableIdx = 0; - if (bwp && - bwp->bwp_Dedicated && - bwp->bwp_Dedicated->pdsch_Config && - bwp->bwp_Dedicated->pdsch_Config->choice.setup && - bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table) { - if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0) - mcsTableIdx = 1; - else - mcsTableIdx = 2; - } - else mcsTableIdx = 0; + NR_PDSCH_Config_t *pdsch_Config = dl_bwp->pdsch_Config; + uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; int dmrsConfigType=0; - if (bwp && - bwp->bwp_Dedicated && - bwp->bwp_Dedicated->pdsch_Config && - bwp->bwp_Dedicated->pdsch_Config->choice.setup && - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA && - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup && - bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type) + if (pdsch_Config && + pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA && + pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup && + pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type) dmrsConfigType = 1; - NR_PDSCH_Config_t *pdsch_config = bwp && bwp->bwp_Dedicated && bwp->bwp_Dedicated->pdsch_Config ? bwp->bwp_Dedicated->pdsch_Config->choice.setup : NULL; - pdsch_pdu_rel15->pduBitmap = 0; pdsch_pdu_rel15->rnti = ra->RA_rnti; pdsch_pdu_rel15->pduIndex = pduindex; pdsch_pdu_rel15->BWPSize = BWPSize; pdsch_pdu_rel15->BWPStart = BWPStart; - pdsch_pdu_rel15->SubcarrierSpacing = genericParameters->subcarrierSpacing; + pdsch_pdu_rel15->SubcarrierSpacing = dl_bwp->scs; pdsch_pdu_rel15->CyclicPrefix = 0; pdsch_pdu_rel15->NrOfCodewords = 1; pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; @@ -1381,7 +1277,7 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->VRBtoPRBMapping = 0; pdsch_pdu_rel15->StartSymbolIndex = startSymbolIndex; pdsch_pdu_rel15->NrOfSymbols = nrOfSymbols; - pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, + pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(pdsch_Config, nr_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, nrOfSymbols, startSymbolIndex, @@ -1421,7 +1317,8 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->TBSize[0] = TBS; } - int bw_tbslbrm = get_bw_tbslbrm(genericParameters, ra->CellGroup); + int scc_bwpsize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int bw_tbslbrm = get_bw_tbslbrm(scc_bwpsize, ra->CellGroup); pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, bw_tbslbrm, 1); @@ -1473,23 +1370,21 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra fill_dci_pdu_rel15(scc, ra->CellGroup, + dl_bwp, &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], &dci_payload, NR_DL_DCI_FORMAT_1_0, NR_RNTI_RA, BWPSize, - bwpid, - coresetid, + dl_bwp->bwp_id, + coreset, nr_mac->cset0_bwp_size); // DL TX request nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; // Program UL processing for Msg3 - NR_BWP_Uplink_t *ubwp = ra->CellGroup ? - ra->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->dl_bwp_id-1] : - NULL; - nr_get_Msg3alloc(module_idP, CC_id, scc, ubwp, slotP, frameP, ra, nr_mac->tdd_beam_association); + nr_get_Msg3alloc(module_idP, CC_id, scc, slotP, frameP, ra, nr_mac->tdd_beam_association); nr_add_msg3(module_idP, CC_id, frameP, slotP, ra, (uint8_t *) &tx_req->TLVs[0].value.direct[0]); if(ra->cfra) { @@ -1527,6 +1422,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; + NR_UE_DL_BWP_t *dl_bwp = &ra->DL_BWP; if (ra->Msg4_frame == frameP && ra->Msg4_slot == slotP ) { @@ -1536,23 +1432,8 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; NR_SearchSpace_t *ss = ra->ra_ss; - NR_BWP_Downlink_t *bwp = NULL; - NR_ControlResourceSet_t *coreset = NULL; - NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList=NULL; - - if (ra->CellGroup && - ra->CellGroup->spCellConfig && - ra->CellGroup->spCellConfig->spCellConfigDedicated && - ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList && - ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id-1]) { - bwp = ra->CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->dl_bwp_id-1]; - pdsch_TimeDomainAllocationList = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } - else { - pdsch_TimeDomainAllocationList = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } - - coreset = ra->coreset; + NR_ControlResourceSet_t *coreset = ra->coreset; + NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList = dl_bwp->tdaList; AssertFatal(coreset!=NULL,"Coreset cannot be null for RA-Msg4\n"); @@ -1571,14 +1452,12 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra LOG_I(NR_MAC,"Generate msg4, rnti: %04x\n", ra->rnti); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - NR_BWP_t *genericParameters = bwp ? & bwp->bwp_Common->genericParameters : &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - long BWPStart = 0; long BWPSize = 0; NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = NULL; if(*ss->controlResourceSetId!=0) { - BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - BWPSize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + BWPStart = dl_bwp->BWPStart; + BWPSize = dl_bwp->BWPSize; } else { type0_PDCCH_CSS_config = &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]; BWPStart = type0_PDCCH_CSS_config->cset_start_rb; @@ -1629,7 +1508,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra } const int delta_PRI=0; - int r_pucch = nr_get_pucch_resource(coreset, sched_ctrl->active_ubwp, NULL, CCEIndex); + int r_pucch = nr_get_pucch_resource(coreset, ra->UL_BWP.pucch_Config, CCEIndex); LOG_D(NR_MAC,"[RAPROC] Msg4 r_pucch %d (CCEIndex %d, nb_of_candidates %d, delta_PRI %d)\n", r_pucch, CCEIndex, nr_of_candidates, delta_PRI); @@ -1688,7 +1567,13 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra uint16_t N_DMRS_SLOT = get_num_dmrs(dlDmrsSymbPos); - long dmrsConfigType = bwp!=NULL ? (bwp->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1) : 0; + NR_PDSCH_Config_t *pdsch_Config = dl_bwp->pdsch_Config; + int dmrsConfigType=0; + if (pdsch_Config && + pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA && + pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup && + pdsch_Config->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type) + dmrsConfigType = 1; nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData = 2; if (nrOfSymbols == 2) { @@ -1708,18 +1593,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra N_PRB_DMRS = nr_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 4; } - uint8_t mcsTableIdx = 0; - if (bwp && - bwp->bwp_Dedicated && - bwp->bwp_Dedicated->pdsch_Config && - bwp->bwp_Dedicated->pdsch_Config->choice.setup && - bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table) { - if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0) - mcsTableIdx = 1; - else - mcsTableIdx = 2; - } - else mcsTableIdx = 0; + uint8_t mcsTableIdx = dl_bwp->mcsTableIdx; int rbStart = 0; int rbSize = 0; @@ -1764,7 +1638,6 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra // look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it. This is especially // important if we have multiple RAs, and the DLSCH has to reuse them, so we need to mark them - const int bwpid = bwp ? bwp->bwp_Id : 0; const int coresetid = coreset->controlResourceSetId; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = nr_mac->pdcch_pdu_idx[CC_id][coresetid]; if (!pdcch_pdu_rel15) { @@ -1774,7 +1647,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2 + sizeof(nfapi_nr_dl_tti_pdcch_pdu)); dl_req->nPDUs += 1; pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; - nr_configure_pdcch(pdcch_pdu_rel15, coreset, genericParameters, &ra->sched_pdcch); + nr_configure_pdcch(pdcch_pdu_rel15, coreset, false, &ra->sched_pdcch); nr_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu_rel15; } @@ -1796,7 +1669,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->pduIndex = pduindex; pdsch_pdu_rel15->BWPSize = BWPSize; pdsch_pdu_rel15->BWPStart = BWPStart; - pdsch_pdu_rel15->SubcarrierSpacing = genericParameters->subcarrierSpacing; + pdsch_pdu_rel15->SubcarrierSpacing = dl_bwp->scs; pdsch_pdu_rel15->CyclicPrefix = 0; pdsch_pdu_rel15->NrOfCodewords = 1; int R = nr_get_code_rate_dl(mcsIndex,mcsTableIdx); @@ -1804,7 +1677,7 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra pdsch_pdu_rel15->qamModOrder[0] = 2; pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; - pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round]; + pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[harq->round%4]; pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; @@ -1825,7 +1698,8 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra int x_Overhead = 0; nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, pdsch_pdu_rel15->numDmrsCdmGrpsNoData, tb_scaling); - int bw_tbslbrm = get_bw_tbslbrm(genericParameters, ra->CellGroup); + int scc_bwpsize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int bw_tbslbrm = get_bw_tbslbrm(scc_bwpsize, ra->CellGroup); pdsch_pdu_rel15->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(mcsTableIdx, bw_tbslbrm, 1); @@ -1890,13 +1764,14 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra fill_dci_pdu_rel15(scc, ra->CellGroup, + dl_bwp, &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], &dci_payload, NR_DL_DCI_FORMAT_1_0, NR_RNTI_TC, pdsch_pdu_rel15->BWPSize, - bwpid, - coresetid, + dl_bwp->bwp_id, + coreset, nr_mac->cset0_bwp_size); // Add padding header and zero rest out if there is space left @@ -1962,19 +1837,8 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra harq->round = 0; harq->ndi ^= 1; - // Pause scheduling according to: - // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs - const NR_COMMON_channels_t *common_channels = &RC.nrmac[module_idP]->common_channels[0]; - const NR_SIB1_t *sib1 = common_channels->sib1 ? common_channels->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, - common_channels->ServingCellConfigCommon, - sib1); - uint32_t delay_ms = servingCellConfig && servingCellConfig->downlinkBWP_ToAddModList ? - NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS; - - sched_ctrl->rrc_processing_timer = (delay_ms << genericParameters->subcarrierSpacing); - LOG_I(NR_MAC, "(%d.%d) Activating RRC processing timer for UE %04x with %d ms\n", frameP, slotP, UE->rnti, delay_ms); + sched_ctrl->rrc_processing_timer = 1; // No need to wait at this point in time, setting it to 1 just to enter in function nr_mac_update_timers + LOG_I(NR_MAC, "(%d.%d) Activating RRC processing timer for UE %04x with %d ms\n", frameP, slotP, UE->rnti, 1); // Reset uplink failure flags/counters/timers at MAC so gNB will resume again scheduling resources for this UE UE->UE_sched_ctrl.pusch_consecutive_dtx_cnt = 0; @@ -2006,16 +1870,11 @@ void nr_check_Msg4_Ack(module_id_t module_id, int CC_id, frame_t frame, sub_fram // Pause scheduling according to: // 3GPP TS 38.331 Section 12 Table 12.1-1: UE performance requirements for RRC procedures for UEs - const NR_COMMON_channels_t *common_channels = &RC.nrmac[module_id]->common_channels[0]; - const NR_SIB1_t *sib1 = common_channels->sib1 ? common_channels->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; const NR_ServingCellConfig_t *servingCellConfig = UE->CellGroup ? UE->CellGroup->spCellConfig->spCellConfigDedicated : NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, - common_channels->ServingCellConfigCommon, - sib1); uint32_t delay_ms = servingCellConfig && servingCellConfig->downlinkBWP_ToAddModList ? NR_RRC_SETUP_DELAY_MS + NR_RRC_BWP_SWITCHING_DELAY_MS : NR_RRC_SETUP_DELAY_MS; - sched_ctrl->rrc_processing_timer = (delay_ms << genericParameters->subcarrierSpacing); + sched_ctrl->rrc_processing_timer = (delay_ms << ra->DL_BWP.scs); LOG_I(NR_MAC, "(%d.%d) Activating RRC processing timer for UE %04x with %d ms\n", frame, slot, UE->rnti, delay_ms); } else { LOG_I(NR_MAC, "(ue rnti 0x%04x) RA Procedure failed at Msg4!\n", ra->rnti); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index e2ceadb889d51facba759e3f5a5ae14a462a0f0b..a531a1c71c6438f2eba6bb62848c7e31bba758eb 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -54,52 +54,6 @@ extern RAN_CONTEXT_t RC; - -uint16_t get_ssboffset_pointa(NR_ServingCellConfigCommon_t *scc,const long band) { - - int ratio; - switch (*scc->ssbSubcarrierSpacing) { - case NR_SubcarrierSpacing_kHz15: - AssertFatal(band <= 95, - "Band %ld is not possible for SSB with 15 kHz SCS\n", - band); - // no band available above 3GHz using 15kHz - ratio = 3; // NRARFCN step is 5 kHz - break; - case NR_SubcarrierSpacing_kHz30: - AssertFatal(band <= 96, - "Band %ld is not possible for SSB with 30 kHz SCS\n", - band); - if (band == 46 || band == 48 || band == 77 || - band == 78 || band == 79 || band == 96) // above 3GHz - ratio = 2; // NRARFCN step is 15 kHz - else - ratio = 6; // NRARFCN step is 5 kHz - break; - case NR_SubcarrierSpacing_kHz120: - AssertFatal(band >= 257, - "Band %ld is not possible for SSB with 120 kHz SCS\n", - band); - ratio = 2; // NRARFCN step is 15 kHz - break; - case NR_SubcarrierSpacing_kHz240: - AssertFatal(band >= 257, - "Band %ld is not possible for SSB with 240 kHz SCS\n", - band); - ratio = 4; // NRARFCN step is 15 kHz - break; - default: - AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n", - *scc->ssbSubcarrierSpacing); - } - - const uint32_t ssb_offset0 = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA; - - return (ssb_offset0/(ratio*12) - 10); // absoluteFrequencySSB is the center of SSB - -} - - void schedule_ssb(frame_t frame, sub_frame_t slot, NR_ServingCellConfigCommon_t *scc, nfapi_nr_dl_tti_request_body_t *dl_req, @@ -190,7 +144,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing; const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; - uint16_t offset_pointa = get_ssboffset_pointa(scc,band); + const uint16_t offset_pointa = gNB->ssb_OffsetPointA; uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset; const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap; @@ -207,8 +161,9 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb); // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters if ((ssb_start_symbol/14) == rel_slot){ + const int prb_offset = offset_pointa >> scs; schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1)); - fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id); + fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id); if (get_softmodem_params()->sa == 1) { get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], frameP, @@ -221,7 +176,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) band, i_ssb, ssb_frame_periodicity, - offset_pointa); + prb_offset); gNB->type0_PDCCH_CSS_config[i_ssb].active = true; } } @@ -235,8 +190,9 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb); // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters if ((ssb_start_symbol/14) == rel_slot){ + const int prb_offset = offset_pointa >> scs; schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1)); - fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id); + fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id); if (get_softmodem_params()->sa == 1) { get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb], frameP, @@ -249,7 +205,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) band, i_ssb, ssb_frame_periodicity, - offset_pointa); + prb_offset); gNB->type0_PDCCH_CSS_config[i_ssb].active = true; } } @@ -264,8 +220,9 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb); // if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters if ((ssb_start_symbol/14) == rel_slot){ + const int prb_offset = offset_pointa >> (scs-2); // reference 60kHz schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1)); - fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id); + fill_ssb_vrb_map(cc, prb_offset, ssbSubcarrierOffset, ssb_start_symbol, CC_id); const NR_TDD_UL_DL_Pattern_t *tdd = &scc->tdd_UL_DL_ConfigurationCommon->pattern1; const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; // FR2 is only TDD, to be fixed for flexible TDD @@ -286,7 +243,7 @@ void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) band, i_ssb, ssb_frame_periodicity, - offset_pointa); + prb_offset); gNB->type0_PDCCH_CSS_config[i_ssb].active = true; } } @@ -306,7 +263,7 @@ void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframe //---------------------------------------- } -void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id) { +void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int ssb_subcarrier_offset, uint16_t symStart, int CC_id) { AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing != NR_SubcarrierSpacing_kHz240, @@ -314,7 +271,8 @@ void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart uint16_t *vrb_map = cc[CC_id].vrb_map; - for (int rb = 0; rb < 20; rb++) + const int extra_prb = ssb_subcarrier_offset > 0; + for (int rb = 0; rb < 20+extra_prb; rb++) vrb_map[rbStart + rb] = SL_to_bitmap(symStart, 4); } @@ -327,7 +285,7 @@ uint32_t schedule_control_sib1(module_id_t module_id, int nrOfSymbols, uint16_t dlDmrsSymbPos, uint8_t candidate_idx, - int num_total_bytes) { + uint16_t num_total_bytes) { gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; NR_COMMON_channels_t *cc = &gNB_mac->common_channels[CC_id]; @@ -352,7 +310,6 @@ uint32_t schedule_control_sib1(module_id_t module_id, } gNB_mac->sched_ctrlCommon->pdsch_semi_static.time_domain_allocation = time_domain_allocation; - gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx = 0; gNB_mac->sched_ctrlCommon->sched_pdsch.mcs = 0; // starting from mcs 0 gNB_mac->sched_ctrlCommon->num_total_bytes = num_total_bytes; @@ -389,6 +346,7 @@ uint32_t schedule_control_sib1(module_id_t module_id, uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->pdsch_semi_static.numDmrsCdmGrpsNoData * 6; uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos); LOG_D(MAC,"dlDmrsSymbPos %x\n",dlDmrsSymbPos); + int mcsTableIdx = 0; int rbSize = 0; uint32_t TBS = 0; do { @@ -400,8 +358,8 @@ uint32_t schedule_control_sib1(module_id_t module_id, else break; } - TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx), - nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx), + TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, mcsTableIdx), + nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, mcsTableIdx), rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0, 0,1) >> 3; } while (TBS < gNB_mac->sched_ctrlCommon->num_total_bytes); @@ -443,7 +401,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, gNB_MAC_INST *gNB_mac = RC.nrmac[Mod_idP]; NR_COMMON_channels_t *cc = gNB_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - + int mcsTableIdx = 0; nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; @@ -452,7 +410,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; nr_configure_pdcch(pdcch_pdu_rel15, gNB_mac->sched_ctrlCommon->coreset, - NULL, + true, // sib1 &gNB_mac->sched_ctrlCommon->sched_pdcch); nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; @@ -479,7 +437,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, pdsch_pdu_rel15->qamModOrder[0] = 2; pdsch_pdu_rel15->mcsIndex[0] = gNB_mac->sched_ctrlCommon->sched_pdsch.mcs; pdsch_pdu_rel15->mcsTable[0] = 0; - pdsch_pdu_rel15->rvIndex[0] = nr_rv_round_map[0]; + pdsch_pdu_rel15->rvIndex[0] = 0; pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; pdsch_pdu_rel15->nrOfLayers = 1; pdsch_pdu_rel15->transmissionScheme = 0; @@ -494,9 +452,9 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, pdsch_pdu_rel15->rbSize = gNB_mac->sched_ctrlCommon->sched_pdsch.rbSize; pdsch_pdu_rel15->VRBtoPRBMapping = 0; pdsch_pdu_rel15->qamModOrder[0] = nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->sched_pdsch.mcs, - gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx); + mcsTableIdx); pdsch_pdu_rel15->TBSize[0] = TBS; - pdsch_pdu_rel15->mcsTable[0] = gNB_mac->sched_ctrlCommon->pdsch_semi_static.mcsTableIdx; + pdsch_pdu_rel15->mcsTable[0] = mcsTableIdx; pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; pdsch_pdu_rel15->dlDmrsSymbPos = dlDmrsSymbPos; @@ -545,6 +503,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, int rnti_type = NR_RNTI_SI; fill_dci_pdu_rel15(scc, + NULL, NULL, &pdcch_pdu_rel15->dci_pdu[pdcch_pdu_rel15->numDlDci - 1], &dci_payload, @@ -552,7 +511,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP, rnti_type, pdsch_pdu_rel15->BWPSize, 0, - 0, + gNB_mac->sched_ctrlCommon->coreset, gNB_mac->cset0_bwp_size); LOG_D(MAC,"BWPSize: %i\n", pdcch_pdu_rel15->BWPSize); @@ -612,7 +571,7 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) // Get SIB1 uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8]; - uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, SI_RNTI, 1, sib1_payload); + uint16_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, SI_RNTI, 1, sib1_payload); LOG_D(NR_MAC,"sib1_sdu_length = %i\n", sib1_sdu_length); LOG_D(NR_MAC,"SIB1: \n"); for (int k=0;k<sib1_sdu_length;k++) @@ -640,7 +599,8 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) startSymbolIndex, nrOfSymbols, dlDmrsSymbPos, - candidate_idx, sib1_sdu_length); + candidate_idx, + sib1_sdu_length); nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; int pdu_index = gNB_mac->pdu_index[0]++; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 3b5c9ffad4e9b84314ffe03b2d9d8a2b4162db94..6aee81fa67237e4c6cb24e3c699fb630a034e13e 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -365,6 +365,18 @@ void nr_store_dlsch_buffer(module_id_t module_id, } } +void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid) { + + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_harq_t *harq = &sched_ctrl->harq_processes[harq_pid]; + + harq->ndi ^= 1; + harq->round = 0; + UE->mac_stats.dl.errors++; + add_tail_nr_list(&sched_ctrl->available_dl_harq, harq_pid); + +} + bool allocate_dl_retransmission(module_id_t module_id, frame_t frame, sub_frame_t slot, @@ -376,32 +388,25 @@ bool allocate_dl_retransmission(module_id_t module_id, gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; const NR_ServingCellConfigCommon_t *scc = nr_mac->common_channels->ServingCellConfigCommon; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; NR_sched_pdsch_t *retInfo = &sched_ctrl->harq_processes[current_harq_pid].sched_pdsch; - NR_CellGroupConfig_t *cg = UE->CellGroup; - - NR_BWP_DownlinkDedicated_t *bwpd = - cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated ? - cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL; - - NR_BWP_UplinkDedicated_t *ubwpd = - cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; + NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; - const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, - RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon, - sib1); + //TODO remove this and handle retransmission with old nrOfLayers + // once ps structure is removed + if(ps->nrOfLayers < retInfo->nrOfLayers) { + LOG_W(NR_MAC,"Cannot schedule retransmission. RI changed from %d to %d\n", + retInfo->nrOfLayers, ps->nrOfLayers); + abort_nr_dl_harq(UE, current_harq_pid); + remove_front_nr_list(&sched_ctrl->retrans_dl_harq); + return false; + } - const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId; - const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + const int coresetid = sched_ctrl->coreset->controlResourceSetId; + const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : dl_bwp->BWPSize; int rbStart = 0; // start wrt BWPstart - NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; int rbSize = 0; const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); AssertFatal(tda>=0,"Unable to find PDSCH time domain allocation in list\n"); @@ -430,11 +435,8 @@ bool allocate_dl_retransmission(module_id_t module_id, /* check whether we need to switch the TDA allocation since the last * (re-)transmission */ if (ps->time_domain_allocation != tda) { - nr_set_pdsch_semi_static(sib1, + nr_set_pdsch_semi_static(dl_bwp, scc, - cg, - sched_ctrl->active_bwp, - bwpd, tda, ps->nrOfLayers, sched_ctrl, @@ -445,11 +447,8 @@ bool allocate_dl_retransmission(module_id_t module_id, * that we have enough resources */ NR_pdsch_semi_static_t temp_ps = *ps; - nr_set_pdsch_semi_static(sib1, + nr_set_pdsch_semi_static(dl_bwp, scc, - cg, - sched_ctrl->active_bwp, - bwpd, tda, ps->nrOfLayers, sched_ctrl, @@ -520,7 +519,7 @@ bool allocate_dl_retransmission(module_id_t module_id, /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH * allocation after CCE alloc fail would be more complex) */ - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex); + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); const int alloc = nr_acknack_scheduling(module_id, UE, frame, slot, r_pucch, 0); if (alloc<0) { LOG_D(MAC, @@ -580,6 +579,7 @@ void pf_dl(module_id_t module_id, continue; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; @@ -619,12 +619,15 @@ void pf_dl(module_id_t module_id, /* Calculate coeff */ const NR_bler_options_t *bo = &mac->dl_bler; - const int max_mcs_table = ps->mcsTableIdx == 1 ? 27 : 28; + const int max_mcs_table = current_BWP->mcsTableIdx == 1 ? 27 : 28; const int max_mcs = min(sched_ctrl->dl_max_mcs, max_mcs_table); - sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame); + if (bo->harq_round_max == 1) + sched_pdsch->mcs = max_mcs; + else + sched_pdsch->mcs = get_mcs_from_bler(bo, stats, &sched_ctrl->dl_bler_stats, max_mcs, frame); UE->layers = set_dl_nrOfLayers(sched_ctrl); - const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); - const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); + const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); + const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, current_BWP->mcsTableIdx); uint32_t tbs = nr_compute_tbs(Qm, R, 1, /* rbSize */ @@ -651,37 +654,16 @@ void pf_dl(module_id_t module_id, /* Loop UE_sched to find max coeff and allocate transmission */ while (remainUEs> 0 && n_rb_sched >= min_rbSize && iterator->UE != NULL) { - NR_CellGroupConfig_t *cg = iterator->UE->CellGroup; - - NR_BWP_DownlinkDedicated_t *bwpd = - cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated ? - cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL; - - NR_BWP_UplinkDedicated_t *ubwpd = - cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; - NR_UE_sched_ctrl_t *sched_ctrl = &iterator->UE->UE_sched_ctrl; const uint16_t rnti = iterator->UE->rnti; - const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? - RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : - NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, - RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon, - sib1); + NR_UE_DL_BWP_t *dl_bwp = &iterator->UE->current_DL_BWP; + NR_UE_UL_BWP_t *ul_bwp = &iterator->UE->current_UL_BWP; - const int coresetid = (sched_ctrl->active_bwp||bwpd) ? - sched_ctrl->coreset->controlResourceSetId : - RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId; + const int coresetid = sched_ctrl->coreset->controlResourceSetId; const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : - NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + dl_bwp->BWPSize; int rbStart = 0; // start wrt BWPstart if (sched_ctrl->available_dl_harq.head < 0) { @@ -721,7 +703,7 @@ void pf_dl(module_id_t module_id, /* Find PUCCH occasion: if it fails, undo CCE allocation (undoing PUCCH * allocation after CCE alloc fail would be more complex) */ - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, ubwpd, CCEIndex); + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, ul_bwp->pucch_Config, CCEIndex); const int alloc = nr_acknack_scheduling(module_id, iterator->UE, frame, slot, r_pucch, 0); if (alloc<0) { @@ -748,11 +730,8 @@ void pf_dl(module_id_t module_id, NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; if (ps->nrOfLayers != iterator->UE->layers || ps->time_domain_allocation != tda ) { - nr_set_pdsch_semi_static(sib1, + nr_set_pdsch_semi_static(dl_bwp, scc, - iterator->UE->CellGroup, - sched_ctrl->active_bwp, - bwpd, tda, iterator->UE->layers, sched_ctrl, @@ -770,8 +749,8 @@ void pf_dl(module_id_t module_id, while (rbStart + max_rbSize < bwpSize && (rballoc_mask[rbStart + max_rbSize] & slbitmap) == slbitmap) max_rbSize++; - sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); - sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); + sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); + sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); sched_pdsch->pucch_allocation = alloc; uint32_t TBS = 0; uint16_t rbSize; @@ -817,30 +796,18 @@ void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t /* This is temporary and it assumes all UEs have the same BWP and TDA*/ NR_UE_info_t *UE=UE_info->list[0]; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); int startSymbolIndex, nrOfSymbols; - const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = sched_ctrl->active_bwp ? - sched_ctrl->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList : - scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + const struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = current_BWP->tdaList; AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count); const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); - const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(sched_ctrl->active_bwp, - RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon, - sib1); - - NR_BWP_DownlinkDedicated_t *bwpd = - UE->CellGroup && - UE->CellGroup->spCellConfig && - UE->CellGroup->spCellConfig->spCellConfigDedicated ? - UE->CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL; - - const int coresetid = (sched_ctrl->active_bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : RC.nrmac[module_id]->sched_ctrlCommon->coreset->controlResourceSetId; + const int coresetid = sched_ctrl->coreset->controlResourceSetId; - const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - const uint16_t BWPStart = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_start : NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); + const uint16_t bwpSize = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_size : current_BWP->BWPSize; + const uint16_t BWPStart = coresetid == 0 ? RC.nrmac[module_id]->cset0_bwp_start : current_BWP->BWPStart; const uint16_t slbitmap = SL_to_bitmap(startSymbolIndex, nrOfSymbols); uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map; @@ -900,13 +867,12 @@ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id) { void nr_schedule_ue_spec(module_id_t module_id, frame_t frame, sub_frame_t slot) { + gNB_MAC_INST *gNB_mac = RC.nrmac[module_id]; if (!is_xlsch_in_slot(gNB_mac->dlsch_slot_bitmap[slot / 64], slot)) return; - //if (slot==7 || slot == 17) return; - /* PREPROCESSOR */ gNB_mac->pre_processor_dl(module_id, frame, slot); const int CC_id = 0; @@ -916,6 +882,7 @@ void nr_schedule_ue_spec(module_id_t module_id, UE_iterator(UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_DL_BWP_t *current_BWP = &UE->current_DL_BWP; if (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0) continue; @@ -923,12 +890,6 @@ void nr_schedule_ue_spec(module_id_t module_id, UE->mac_stats.dl.current_bytes = 0; NR_CellGroupConfig_t *cg = UE->CellGroup; - NR_BWP_DownlinkDedicated_t *bwpd = - cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated ? - cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP : NULL; - /* update TA and set ta_apply every 10 frames. * Possible improvement: take the periodicity from input file. * If such UE is not scheduled now, it will be by the preprocessor later. @@ -995,24 +956,16 @@ void nr_schedule_ue_spec(module_id_t module_id, TBS, current_harq_pid, harq->round, - nr_rv_round_map[harq->round], + nr_rv_round_map[harq->round%4], harq->ndi, pucch->timing_indicator, pucch->frame, pucch->ul_slot, sched_pdsch->pucch_allocation, sched_ctrl->tpc1); - NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp; - const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - NR_BWP_t *genericParameters = get_dl_bwp_genericParameters(bwp, - RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon, - sib1); - - NR_SearchSpace_t *ss = (bwp||bwpd) ? sched_ctrl->search_space : gNB_mac->sched_ctrlCommon->search_space; - - const int bwp_id = bwp ? bwp->bwp_Id : 0; - const int coresetid = (bwp||bwpd) ? sched_ctrl->coreset->controlResourceSetId : gNB_mac->sched_ctrlCommon->coreset->controlResourceSetId; + const int bwp_id = current_BWP->bwp_id; + const int coresetid = sched_ctrl->coreset->controlResourceSetId; /* look up the PDCCH PDU for this CC, BWP, and CORESET. If it does not exist, create it */ nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = gNB_mac->pdcch_pdu_idx[CC_id][coresetid]; @@ -1026,8 +979,8 @@ void nr_schedule_ue_spec(module_id_t module_id, dl_req->nPDUs += 1; pdcch_pdu = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; LOG_D(NR_MAC,"Trying to configure DL pdcch for UE %04x, bwp %d, cs %d\n", UE->rnti, bwp_id, coresetid); - NR_ControlResourceSet_t *coreset = (bwp||bwpd)? sched_ctrl->coreset:gNB_mac->sched_ctrlCommon->coreset; - nr_configure_pdcch(pdcch_pdu, coreset, genericParameters, &sched_ctrl->sched_pdcch); + NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; + nr_configure_pdcch(pdcch_pdu, coreset, false, &sched_ctrl->sched_pdcch); gNB_mac->pdcch_pdu_idx[CC_id][coresetid] = pdcch_pdu; } @@ -1049,22 +1002,22 @@ void nr_schedule_ue_spec(module_id_t module_id, pdsch_pdu->BWPSize = gNB_mac->cset0_bwp_size; pdsch_pdu->BWPStart = gNB_mac->cset0_bwp_start; } else { - pdsch_pdu->BWPSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - pdsch_pdu->BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); + pdsch_pdu->BWPSize = current_BWP->BWPSize; + pdsch_pdu->BWPStart = current_BWP->BWPStart; } - pdsch_pdu->SubcarrierSpacing = genericParameters->subcarrierSpacing; - pdsch_pdu->CyclicPrefix = genericParameters->cyclicPrefix ? *genericParameters->cyclicPrefix : 0; + pdsch_pdu->SubcarrierSpacing = current_BWP->scs; + pdsch_pdu->CyclicPrefix = current_BWP->cyclicprefix ? *current_BWP->cyclicprefix : 0; // Codeword information pdsch_pdu->NrOfCodewords = 1; //number of information bits per 1024 coded bits expressed in 0.1 bit units pdsch_pdu->targetCodeRate[0] = R; pdsch_pdu->qamModOrder[0] = Qm; pdsch_pdu->mcsIndex[0] = sched_pdsch->mcs; - pdsch_pdu->mcsTable[0] = ps->mcsTableIdx; + pdsch_pdu->mcsTable[0] = current_BWP->mcsTableIdx; AssertFatal(harq!=NULL,"harq is null\n"); - AssertFatal(harq->round<4,"%d",harq->round); - pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round]; + AssertFatal(harq->round<gNB_mac->dl_bler.harq_round_max,"%d",harq->round); + pdsch_pdu->rvIndex[0] = nr_rv_round_map[harq->round%4]; pdsch_pdu->TBSize[0] = TBS; pdsch_pdu->dataScramblingId = *scc->physCellId; pdsch_pdu->nrOfLayers = nrOfLayers; @@ -1098,22 +1051,17 @@ void nr_schedule_ue_spec(module_id_t module_id, csi_report->codebook_mode); } // TBS_LBRM according to section 5.4.2.1 of 38.212 - long *maxMIMO_Layers = cg->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->ext1->maxMIMO_Layers; + long *maxMIMO_Layers = current_BWP->pdsch_servingcellconfig->ext1->maxMIMO_Layers; AssertFatal (maxMIMO_Layers != NULL,"Option with max MIMO layers not configured is not supported\n"); int nl_tbslbrm = *maxMIMO_Layers < 4 ? *maxMIMO_Layers : 4; // Maximum number of PRBs across all configured DL BWPs - int bw_tbslbrm = get_bw_tbslbrm(genericParameters, cg); - pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(ps->mcsTableIdx, + int scc_bwpsize = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + int bw_tbslbrm = get_bw_tbslbrm(scc_bwpsize, cg); + pdsch_pdu->maintenance_parms_v3.tbSizeLbrmBytes = nr_compute_tbslbrm(current_BWP->mcsTableIdx, bw_tbslbrm, nl_tbslbrm); - NR_PDSCH_Config_t *pdsch_Config=NULL; - - if (bwp && - bwp->bwp_Dedicated && - bwp->bwp_Dedicated->pdsch_Config && - bwp->bwp_Dedicated->pdsch_Config->choice.setup) - pdsch_Config = bwp->bwp_Dedicated->pdsch_Config->choice.setup; + NR_PDSCH_Config_t *pdsch_Config = current_BWP->pdsch_Config; /* Check and validate PTRS values */ struct NR_SetupRelease_PTRS_DownlinkConfig *phaseTrackingRS = @@ -1160,14 +1108,11 @@ void nr_schedule_ue_spec(module_id_t module_id, dci_pdu_rel15_t dci_payload; memset(&dci_payload, 0, sizeof(dci_pdu_rel15_t)); // bwp indicator - const int n_dl_bwp = bwp ? cg->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count : 0; - AssertFatal(n_dl_bwp <= NR_MAX_NUM_BWP, "downlinkBWP_ToAddModList has %d BWP!\n", n_dl_bwp); - // as per table 7.3.1.1.2-1 in 38.212 - dci_payload.bwp_indicator.val = bwp ? (n_dl_bwp < 4 ? bwp->bwp_Id : bwp->bwp_Id - 1) : 0; + dci_payload.bwp_indicator.val = current_BWP->n_dl_bwp < 4 ? bwp_id : bwp_id - 1; - if (bwp) AssertFatal(bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1, - "Only frequency resource allocation type 1 is currently supported\n"); + AssertFatal(pdsch_Config->resourceAllocation == NR_PDSCH_Config__resourceAllocation_resourceAllocationType1, + "Only frequency resource allocation type 1 is currently supported\n"); dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu->rbSize, pdsch_pdu->rbStart, @@ -1203,19 +1148,17 @@ void nr_schedule_ue_spec(module_id_t module_id, dci_payload.tpc, pucch->timing_indicator); - int dci_format = ss && ss->searchSpaceType && ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific ? - NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0; - const int rnti_type = NR_RNTI_C; fill_dci_pdu_rel15(scc, cg, + current_BWP, dci_pdu, &dci_payload, - dci_format, + current_BWP->dci_format, rnti_type, pdsch_pdu->BWPSize, - bwp ? bwp->bwp_Id : 0, - coresetid, + bwp_id, + sched_ctrl->coreset, gNB_mac->cset0_bwp_size); LOG_D(NR_MAC, @@ -1296,7 +1239,7 @@ void nr_schedule_ue_spec(module_id_t module_id, lcid < 4 ? "DCCH" : "DTCH", lcid, ndata, - bufEnd-buf-+sizeof(NR_MAC_SUBHEADER_LONG)); + bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG)); if (len == 0) break; @@ -1327,6 +1270,8 @@ void nr_schedule_ue_spec(module_id_t module_id, header->L = htons(bufEnd-buf); dlsch_total_bytes += bufEnd-buf; + for (; ((intptr_t)buf) % 4; buf++) + *buf = lrand48() & 0xff; for (; buf < bufEnd - 3; buf += 4) { uint32_t *buf32 = (uint32_t *)buf; *buf32 = lrand48(); @@ -1355,6 +1300,8 @@ void nr_schedule_ue_spec(module_id_t module_id, /* save which time allocation has been used, to be used on * retransmissions */ harq->sched_pdsch.time_domain_allocation = ps->time_domain_allocation; + /* save nr of layers for retransmissions */ + harq->sched_pdsch.nrOfLayers = ps->nrOfLayers; // ta command is sent, values are reset if (sched_ctrl->ta_apply) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 808fc613f1a854d7b410b7a5e28b82ea05aeaa3f..e474315de780568549570a1eff7e5f53acaa908a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -195,17 +195,18 @@ void nr_preprocessor_phytest(module_id_t module_id, NR_UE_info_t *UE = RC.nrmac[module_id]->UE_info.list[0]; NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; const int CC_id = 0; const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; ps->nrOfLayers = target_dl_Nl; if (ps->time_domain_allocation != tda || ps->nrOfLayers != target_dl_Nl) - nr_set_pdsch_semi_static(NULL, scc, UE->CellGroup, sched_ctrl->active_bwp, NULL, tda, target_dl_Nl,sched_ctrl , ps); + nr_set_pdsch_semi_static(dl_bwp, scc, tda, target_dl_Nl,sched_ctrl , ps); /* find largest unallocated chunk */ - const int bwpSize = NRRIV2BW(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - const int BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_bwp->bwp_Common->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const int bwpSize = dl_bwp->BWPSize; + const int BWPStart = dl_bwp->BWPStart; int rbStart = 0; int rbSize = 0; @@ -278,7 +279,7 @@ void nr_preprocessor_phytest(module_id_t module_id, __func__, UE->rnti); - int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, sched_ctrl->active_ubwp, NULL, CCEIndex); + int r_pucch = nr_get_pucch_resource(sched_ctrl->coreset, UE->current_UL_BWP.pucch_Config, CCEIndex); const int alloc = nr_acknack_scheduling(module_id, UE, frame, slot, r_pucch, 0); if (alloc < 0) { LOG_D(MAC, @@ -308,9 +309,9 @@ void nr_preprocessor_phytest(module_id_t module_id, sched_pdsch->rbSize = rbSize; sched_pdsch->mcs = target_dl_mcs; + sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); + sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, dl_bwp->mcsTableIdx); sched_ctrl->dl_bler_stats.mcs = target_dl_mcs; /* for logging output */ - sched_pdsch->Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx); - sched_pdsch->R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx); sched_pdsch->tb_size = nr_compute_tbs(sched_pdsch->Qm, sched_pdsch->R, sched_pdsch->rbSize, @@ -340,7 +341,6 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; - const int mu = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing; NR_UE_info_t *UE = nr_mac->UE_info.list[0]; AssertFatal(nr_mac->UE_info.list[1] == NULL, @@ -351,9 +351,10 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ const int CC_id = 0; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + const int mu = ul_bwp->scs; - const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = - sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + const struct NR_PUSCH_TimeDomainResourceAllocationList *tdaList = ul_bwp->tdaList; const int temp_tda = get_ul_tda(nr_mac, scc, slot); if (temp_tda < 0) return false; @@ -361,7 +362,7 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ "time domain assignment %d >= %d\n", temp_tda, tdaList->list.count); - int K2 = get_K2(scc,NULL,sched_ctrl->active_ubwp, temp_tda, mu); + int K2 = get_K2(ul_bwp->tdaList, temp_tda, mu); const int sched_frame = frame + (slot + K2 >= nr_slots_per_frame[mu]); const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; const int tda = get_ul_tda(nr_mac, scc, sched_slot); @@ -377,33 +378,19 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ if (!is_xlsch_in_slot(ulsch_slot_bitmap, sched_slot)) return false; - const long f = (sched_ctrl->active_bwp && sched_ctrl->search_space && - sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ? - sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0; - const int dci_format = f ? NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; - uint8_t num_dmrs_cdm_grps_no_data = 1; - if ((target_ul_Nl==4)||(target_ul_Nl==3)) - num_dmrs_cdm_grps_no_data = 2; - /* we want to avoid a lengthy deduction of DMRS and other parameters in - * every TTI if we can save it, so check whether dci_format, TDA, or + * every TTI if we can save it, so check whether TDA, or * num_dmrs_cdm_grps_no_data has changed and only then recompute */ NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format - || ps->nrOfLayers != target_ul_Nl - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) - nr_set_pusch_semi_static(NULL, scc, sched_ctrl->active_ubwp, NULL,dci_format, tda, num_dmrs_cdm_grps_no_data,target_ul_Nl,ps); + || ps->nrOfLayers != target_ul_Nl) + nr_set_pusch_semi_static(ul_bwp, scc, tda, target_ul_Nl,ps); uint16_t rbStart = 0; uint16_t rbSize; - const int bw = NRRIV2BW(sched_ctrl->active_ubwp ? - sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); - const int BWPStart = NRRIV2PRBOFFSET(sched_ctrl->active_ubwp ? - sched_ctrl->active_ubwp->bwp_Common->genericParameters.locationAndBandwidth : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + const int bw = ul_bwp->BWPSize; + const int BWPStart = ul_bwp->BWPStart; if (target_ul_bw>bw) rbSize = bw; @@ -466,10 +453,10 @@ bool nr_ul_preprocessor_phytest(module_id_t module_id, frame_t frame, sub_frame_ /* Calculate TBS from MCS */ ps->nrOfLayers = target_ul_Nl; - sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table); - sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table); - if (ps->pusch_Config->tp_pi2BPSK - && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) { + sched_pusch->R = nr_get_code_rate_ul(mcs, ul_bwp->mcs_table); + sched_pusch->Qm = nr_get_Qm_ul(mcs, ul_bwp->mcs_table); + if (ul_bwp->pusch_Config->tp_pi2BPSK + && ((ul_bwp->mcs_table == 3 && mcs < 2) || (ul_bwp->mcs_table == 4 && mcs < 6))) { sched_pusch->R >>= 1; sched_pusch->Qm <<= 1; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 3cbffa608fd27e451e08f710e6e4a6831a429d72..1475abc08abfee060726fd83f00ad4b601c19397 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -44,9 +44,12 @@ #include "OCG.h" #include "OCG_extern.h" +/* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */ #include "RRC/LTE/rrc_extern.h" #include "RRC/NR/nr_rrc_extern.h" +#include "RRC/NR/rrc_gNB_UE_context.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +#include "RRC/NR/MESSAGES/asn1_msg.h" #include "intertask_interface.h" @@ -245,54 +248,12 @@ void set_dl_dmrs_ports(NR_pdsch_semi_static_t *ps) { } } -NR_BWP_t *get_dl_bwp_genericParameters(NR_BWP_Downlink_t *active_bwp, - NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1) { - NR_BWP_t *genericParameters = NULL; - if (active_bwp) { - genericParameters = &active_bwp->bwp_Common->genericParameters; - } else if (ServingCellConfigCommon) { - genericParameters = &ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - } else { - genericParameters = &sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.genericParameters; - } - return genericParameters; -} - -NR_BWP_t *get_ul_bwp_genericParameters(NR_BWP_Uplink_t *active_ubwp, - NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1) { - NR_BWP_t *genericParameters = NULL; - if (active_ubwp) { - genericParameters = &active_ubwp->bwp_Common->genericParameters; - } else if (ServingCellConfigCommon) { - genericParameters = &ServingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP->genericParameters; - } else { - genericParameters = &sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.genericParameters; - } - return genericParameters; -} - -NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(const NR_BWP_Downlink_t *active_bwp, - const NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1) { - NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList = NULL; - if (active_bwp) { - tdaList = active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } else if (ServingCellConfigCommon) { - tdaList = ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } else { - tdaList = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; - } - return tdaList; -} - - NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, void *bwp, NR_SearchSpace_t *ss, NR_SearchSpace__searchSpaceType_PR ss_type) { + NR_ControlResourceSetId_t coreset_id = *ss->controlResourceSetId; if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { // common search space @@ -324,29 +285,22 @@ NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, } } -NR_SearchSpace_t *get_searchspace(const NR_SIB1_t *sib1, - NR_ServingCellConfigCommon_t *scc, +NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc, NR_BWP_DownlinkDedicated_t *bwp_Dedicated, NR_SearchSpace__searchSpaceType_PR target_ss) { int n = 0; - if(bwp_Dedicated) { + if(bwp_Dedicated) n = bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count; - } else if(scc) { + else n = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count; - } else { - n = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.count; - } for (int i=0;i<n;i++) { NR_SearchSpace_t *ss = NULL; - if(bwp_Dedicated) { + if(bwp_Dedicated) ss = bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; - } else if(scc) { + else ss = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i]; - } else { - ss = sib1->servingCellConfigCommon->downlinkConfigCommon.initialDownlinkBWP.pdcch_ConfigCommon->choice.setup->commonSearchSpaceList->list.array[i]; - } AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n"); AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n"); if (ss->searchSpaceType->present == target_ss) { @@ -557,11 +511,8 @@ bool nr_find_nb_rb(uint16_t Qm, return *tbs >= bytes && *nb_rb <= nb_rb_max; } -void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1, +void nr_set_pdsch_semi_static(const NR_UE_DL_BWP_t *dl_bwp, const NR_ServingCellConfigCommon_t *scc, - const NR_CellGroupConfig_t *secondaryCellGroup, - const NR_BWP_Downlink_t *bwp, - const NR_BWP_DownlinkDedicated_t *bwpd0, int tda, uint8_t layers, NR_UE_sched_ctrl_t *sched_ctrl, @@ -569,39 +520,11 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1, { bool reset_dmrs = false; - NR_BWP_DownlinkDedicated_t *bwpd = NULL; - if (bwp && bwp->bwp_Dedicated) { - bwpd = bwp->bwp_Dedicated; - } else { - bwpd = (NR_BWP_DownlinkDedicated_t*)bwpd0; - } - - // Prevent gNB to enable 256QAM table while the RRCProcessing timer is running. - // For example, after the RRC created RRC Reconfiguration message we need to prevent gNB to apply another MCS table - // before the RRC Reconfiguration being received by the UE, otherwise UE will not be able to decode PDSCH - // and the connection will drop. - if (sched_ctrl->rrc_processing_timer == 0) { - if (bwpd && - bwpd->pdsch_Config && - bwpd->pdsch_Config->choice.setup && - bwpd->pdsch_Config->choice.setup->mcs_Table) { - if (*bwpd->pdsch_Config->choice.setup->mcs_Table == 0) { - ps->mcsTableIdx = 1; - } else { - ps->mcsTableIdx = 2; - } - } else { - ps->mcsTableIdx = 0; - } - } - LOG_D(NR_MAC,"MCS Table Index: %d\n",ps->mcsTableIdx); - - NR_PDSCH_Config_t *pdsch_Config = NULL; - if (bwpd && bwpd->pdsch_Config) pdsch_Config = bwpd->pdsch_Config->choice.setup; + NR_PDSCH_Config_t *pdsch_Config = dl_bwp->pdsch_Config; LOG_D(NR_MAC,"tda %d, ps->time_domain_allocation %d,layers %d, ps->nrOfLayers %d, pdsch_config %p\n",tda,ps->time_domain_allocation,layers,ps->nrOfLayers,pdsch_Config); reset_dmrs = true; ps->time_domain_allocation = tda; - NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList = get_pdsch_TimeDomainAllocationList(bwp, scc, sib1); + NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList = dl_bwp->tdaList; AssertFatal(tda < tdaList->list.count, "time_domain_allocation %d>=%d\n", tda, tdaList->list.count); ps->mapping_type = tdaList->list.array[tda]->mappingType; if (pdsch_Config) { @@ -615,19 +538,7 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1, const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &ps->startSymbolIndex, &ps->nrOfSymbols); - const long f = ((bwp || bwpd) && - sched_ctrl->search_space && - sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ? - sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats : 0; - - int dci_format; - if (sched_ctrl->search_space) { - dci_format = f ? NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0; - } - else { - dci_format = NR_DL_DCI_FORMAT_1_0; - } - if (dci_format == NR_DL_DCI_FORMAT_1_0) { + if (dl_bwp->dci_format == NR_DL_DCI_FORMAT_1_0) { if (ps->nrOfSymbols == 2) ps->numDmrsCdmGrpsNoData = 1; else @@ -648,72 +559,38 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1, ps->N_PRB_DMRS = ps->numDmrsCdmGrpsNoData * (ps->dmrsConfigType == NFAPI_NR_DMRS_TYPE1 ? 6 : 4); if (reset_dmrs) { - ps->dl_dmrs_symb_pos = fill_dmrs_mask(bwpd ? bwpd->pdsch_Config->choice.setup : NULL, scc ? scc->dmrs_TypeA_Position : 0, ps->nrOfSymbols, ps->startSymbolIndex, ps->mapping_type, ps->frontloaded_symb); + ps->dl_dmrs_symb_pos = fill_dmrs_mask(pdsch_Config, scc ? scc->dmrs_TypeA_Position : 0, ps->nrOfSymbols, ps->startSymbolIndex, ps->mapping_type, ps->frontloaded_symb); ps->N_DMRS_SLOT = get_num_dmrs(ps->dl_dmrs_symb_pos); } - LOG_D(NR_MAC,"bwpd0 %p, bwpd %p : Filling dmrs info, ps->N_PRB_DMRS %d, ps->dl_dmrs_symb_pos %x, ps->N_DMRS_SLOT %d\n",bwpd0,bwpd,ps->N_PRB_DMRS,ps->dl_dmrs_symb_pos,ps->N_DMRS_SLOT); + LOG_D(NR_MAC,"Filling dmrs info, ps->N_PRB_DMRS %d, ps->dl_dmrs_symb_pos %x, ps->N_DMRS_SLOT %d\n",ps->N_PRB_DMRS,ps->dl_dmrs_symb_pos,ps->N_DMRS_SLOT); } -void nr_set_pusch_semi_static(const NR_SIB1_t *sib1, +void nr_set_pusch_semi_static(const NR_UE_UL_BWP_t *ul_bwp, const NR_ServingCellConfigCommon_t *scc, - const NR_BWP_Uplink_t *ubwp, - const NR_BWP_UplinkDedicated_t *ubwpd, - long dci_format, int tda, - uint8_t num_dmrs_cdm_grps_no_data, uint8_t nrOfLayers, NR_pusch_semi_static_t *ps) { - ps->dci_format = dci_format; ps->time_domain_allocation = tda; - NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList = NULL; - if(ubwp) { - tdaList = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else if(scc) { - tdaList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else { - tdaList = sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } - - const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; + const int startSymbolAndLength = ul_bwp->tdaList->list.array[tda]->startSymbolAndLength; SLIV2SL(startSymbolAndLength, &ps->startSymbolIndex, &ps->nrOfSymbols); - ps->pusch_Config = ubwp && ubwp->bwp_Dedicated && ubwp->bwp_Dedicated->pusch_Config ? - ubwp->bwp_Dedicated->pusch_Config->choice.setup : (ubwpd ? ubwpd->pusch_Config->choice.setup : NULL); - if (ps->pusch_Config == NULL || !ps->pusch_Config->transformPrecoder) - ps->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; - else - ps->transform_precoding = *ps->pusch_Config->transformPrecoder; - const int target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - if (ps->transform_precoding) - ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config ? ps->pusch_Config->mcs_Table : NULL, - 0, - ps->dci_format, - NR_RNTI_C, - target_ss, - false); - else { - ps->mcs_table = get_pusch_mcs_table(ps->pusch_Config ? ps->pusch_Config->mcs_TableTransformPrecoder : NULL, - 1, - ps->dci_format, - NR_RNTI_C, - target_ss, - false); - num_dmrs_cdm_grps_no_data = 2; // in case of transform precoding - no Data sent in DMRS symbol - } - ps->nrOfLayers = nrOfLayers; - ps->num_dmrs_cdm_grps_no_data = num_dmrs_cdm_grps_no_data; + // TODO setting of cdm groups with no data to be redone for MIMO + if (ul_bwp->transform_precoding || nrOfLayers<3) + ps->num_dmrs_cdm_grps_no_data = (ul_bwp->dci_format == NR_UL_DCI_FORMAT_0_1) ? 1 : (ps->nrOfSymbols == 2 ? 1 : 2); + else + ps->num_dmrs_cdm_grps_no_data = 2; /* DMRS calculations */ - ps->mapping_type = tdaList->list.array[tda]->mappingType; - ps->NR_DMRS_UplinkConfig = ps->pusch_Config ? + ps->mapping_type = ul_bwp->tdaList->list.array[tda]->mappingType; + ps->NR_DMRS_UplinkConfig = ul_bwp->pusch_Config ? (ps->mapping_type == NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeA ? - ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : - ps->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup) : NULL; + ul_bwp->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeA->choice.setup : + ul_bwp->pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup) : NULL; ps->dmrs_config_type = ps->NR_DMRS_UplinkConfig ? ((ps->NR_DMRS_UplinkConfig->dmrs_Type == NULL ? 0 : 1)) : 0; const pusch_dmrs_AdditionalPosition_t additional_pos = ps->NR_DMRS_UplinkConfig ? (ps->NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL @@ -735,8 +612,8 @@ void nr_set_pusch_semi_static(const NR_SIB1_t *sib1, num_dmrs_symb += (ps->ul_dmrs_symb_pos >> i) & 1; ps->num_dmrs_symb = num_dmrs_symb; ps->N_PRB_DMRS = ps->dmrs_config_type == 0 - ? num_dmrs_cdm_grps_no_data * 6 - : num_dmrs_cdm_grps_no_data * 4; + ? ps->num_dmrs_cdm_grps_no_data * 6 + : ps->num_dmrs_cdm_grps_no_data * 4; } #define BLER_UPDATE_FRAME 10 @@ -1003,25 +880,18 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, } void config_uldci(const NR_SIB1_t *sib1, - const NR_BWP_Uplink_t *ubwp, - const NR_BWP_UplinkDedicated_t *ubwpd, const NR_ServingCellConfigCommon_t *scc, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, - int dci_format, int time_domain_assignment, uint8_t tpc, - int n_ubwp, - int bwp_id) { - - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters((NR_BWP_Uplink_t *)ubwp, - (NR_ServingCellConfigCommon_t *)scc, - (NR_SIB1_t *)sib1); + NR_UE_UL_BWP_t *ul_bwp) { - const int bw = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + int bwp_id = ul_bwp->bwp_id; + nr_dci_format_t dci_format = ul_bwp->dci_format; dci_pdu_rel15->frequency_domain_assignment.val = - PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, bw); + PRBalloc_to_locationandbandwidth0(pusch_pdu->rb_size, pusch_pdu->rb_start, ul_bwp->BWPSize); dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment; dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping; dci_pdu_rel15->mcs = pusch_pdu->mcs_index; @@ -1029,9 +899,9 @@ void config_uldci(const NR_SIB1_t *sib1, dci_pdu_rel15->rv = pusch_pdu->pusch_data.rv_index; dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id; dci_pdu_rel15->tpc = tpc; - const NR_BWP_UplinkDedicated_t *ubwpd2 = (ubwp) ? ubwp->bwp_Dedicated : ubwpd; + NR_PUSCH_Config_t *pusch_Config = ul_bwp->pusch_Config; - if (ubwpd2) AssertFatal(ubwpd2->pusch_Config->choice.setup->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1, + if (pusch_Config) AssertFatal(pusch_Config->resourceAllocation == NR_PUSCH_Config__resourceAllocation_resourceAllocationType1, "Only frequency resource allocation type 1 is currently supported\n"); switch (dci_format) { case NR_UL_DCI_FORMAT_0_0: @@ -1041,13 +911,11 @@ void config_uldci(const NR_SIB1_t *sib1, LOG_D(NR_MAC,"Configuring DCI Format 0_1\n"); dci_pdu_rel15->dai[0].val = 0; //TODO // bwp indicator as per table 7.3.1.1.2-1 in 38.212 - dci_pdu_rel15->bwp_indicator.val = n_ubwp < 4 ? bwp_id : bwp_id - 1; + dci_pdu_rel15->bwp_indicator.val = ul_bwp->n_ul_bwp < 4 ? bwp_id : bwp_id - 1; // SRS resource indicator - if (ubwpd2 && - ubwpd2->pusch_Config && - ubwpd2->pusch_Config->choice.setup && - ubwpd2->pusch_Config->choice.setup->txConfig != NULL) { - AssertFatal(*ubwpd2->pusch_Config->choice.setup->txConfig == NR_PUSCH_Config__txConfig_codebook, + if (pusch_Config && + pusch_Config->txConfig != NULL) { + AssertFatal(*pusch_Config->txConfig == NR_PUSCH_Config__txConfig_codebook, "Non Codebook configuration non supported\n"); dci_pdu_rel15->srs_resource_indicator.val = 0; // taking resource 0 for SRS } @@ -1098,7 +966,7 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) { void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_ControlResourceSet_t *coreset, - NR_BWP_t *bwp, + bool is_sib1, NR_sched_pdcch_t *pdcch) { @@ -1122,7 +990,7 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, pdcch_pdu->ShiftIndex = pdcch->ShiftIndex; if(coreset->controlResourceSetId == 0) { - if(bwp == NULL) + if(is_sib1) pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_MIB_SIB1; else pdcch_pdu->CoreSetType = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG_CSET_0; @@ -1135,11 +1003,10 @@ void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, } int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset, - NR_BWP_Uplink_t *bwp, - NR_BWP_UplinkDedicated_t *bwpd, + NR_PUCCH_Config_t *pucch_Config, int CCEIndex) { int r_pucch = -1; - if(bwp == NULL && bwpd == NULL) { + if(pucch_Config == NULL) { int n_rb,rb_offset; get_coreset_rballoc(coreset->frequencyDomainResources.buf,&n_rb,&rb_offset); const uint16_t N_cce = n_rb * coreset->duration / NR_NB_REG_PER_CCE; @@ -1150,24 +1017,20 @@ int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset, } // This function configures pucch pdu fapi structure -void nr_configure_pucch(const NR_SIB1_t *sib1, - nfapi_nr_pucch_pdu_t* pucch_pdu, +void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, NR_ServingCellConfigCommon_t *scc, - NR_CellGroupConfig_t *CellGroup, - NR_BWP_Uplink_t *bwp, - NR_BWP_UplinkDedicated_t *bwpd, - uint16_t rnti, + NR_UE_info_t* UE, uint8_t pucch_resource, uint16_t O_csi, uint16_t O_ack, uint8_t O_sr, int r_pucch) { - NR_PUCCH_Config_t *pucch_Config; NR_PUCCH_Resource_t *pucchres; NR_PUCCH_ResourceSet_t *pucchresset; NR_PUCCH_FormatConfig_t *pucchfmt; NR_PUCCH_ResourceId_t *resource_id = NULL; + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; long *id0 = NULL; int n_list, n_set; @@ -1179,12 +1042,7 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, uint16_t O_uci = O_csi + O_ack; - NR_PUSCH_Config_t *pusch_Config = NULL; - if(bwp && bwp->bwp_Dedicated && bwp->bwp_Dedicated->pusch_Config) { - pusch_Config = bwp->bwp_Dedicated->pusch_Config->choice.setup; - } else if(bwpd && bwpd->pusch_Config) { - pusch_Config = bwpd->pusch_Config->choice.setup; - } + NR_PUSCH_Config_t *pusch_Config = current_BWP->pusch_Config; long *pusch_id = pusch_Config ? pusch_Config->dataScramblingIdentityPUSCH : NULL; @@ -1194,14 +1052,7 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, id0 = pusch_Config->dmrs_UplinkForPUSCH_MappingTypeB->choice.setup->transformPrecodingDisabled->scramblingID0; else id0 = scc->physCellId; - NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon = NULL; - if(bwp) { - pucch_ConfigCommon = bwp->bwp_Common->pucch_ConfigCommon->choice.setup; - } else if(scc) { - pucch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup; - } else { - pucch_ConfigCommon = sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pucch_ConfigCommon->choice.setup; - } + NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon = current_BWP->pucch_ConfigCommon; // hop flags and hopping id are valid for any BWP switch (pucch_ConfigCommon->pucch_GroupHopping){ @@ -1229,18 +1080,14 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, else pucch_pdu->hopping_id = *scc->physCellId; - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(bwp,scc, sib1); + pucch_pdu->bwp_size = current_BWP->BWPSize; + pucch_pdu->bwp_start = current_BWP->BWPStart; + pucch_pdu->subcarrier_spacing = current_BWP->scs; + pucch_pdu->cyclic_prefix = (current_BWP->cyclicprefix==NULL) ? 0 : *current_BWP->cyclicprefix; - pucch_pdu->bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - pucch_pdu->bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - pucch_pdu->subcarrier_spacing = genericParameters->subcarrierSpacing; - pucch_pdu->cyclic_prefix = (genericParameters->cyclicPrefix==NULL) ? 0 : *genericParameters->cyclicPrefix; - if (r_pucch<0 || bwp ){ + NR_PUCCH_Config_t *pucch_Config = current_BWP->pucch_Config; + if (r_pucch<0 || pucch_Config){ LOG_D(NR_MAC,"pucch_acknak: Filling dedicated configuration for PUCCH\n"); - // we have either a dedicated BWP or Dedicated PUCCH configuration on InitialBWP - AssertFatal(bwp!=NULL || bwpd!=NULL,"We need one dedicated configuration for a BWP (neither additional or initial BWP has a dedicated configuration)\n"); - pucch_Config = bwp && bwp->bwp_Dedicated && bwp->bwp_Dedicated->pucch_Config ? - bwp->bwp_Dedicated->pucch_Config->choice.setup : bwpd->pucch_Config->choice.setup; AssertFatal(pucch_Config->resourceSetToAddModList!=NULL, "PUCCH resourceSetToAddModList is null\n"); @@ -1293,7 +1140,7 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, if (pucchres->pucch_ResourceId == *resource_id) { res_found = 1; pucch_pdu->prb_start = pucchres->startingPRB; - pucch_pdu->rnti = rnti; + pucch_pdu->rnti = UE->rnti; // FIXME why there is only one frequency hopping flag // what about inter slot frequency hopping? pucch_pdu->freq_hop_flag = pucchres->intraSlotFrequencyHopping!= NULL ? 1 : 0; @@ -1382,8 +1229,8 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, LOG_D(NR_MAC,"Configure pucch: pucch_pdu->format_type %d pucch_pdu->bit_len_harq %d, pucch->pdu->bit_len_csi %d\n",pucch_pdu->format_type,pucch_pdu->bit_len_harq,pucch_pdu->bit_len_csi_part1); } else { // this is the default PUCCH configuration, PUCCH format 0 or 1 - LOG_D(NR_MAC,"pucch_acknak: Filling default PUCCH configuration from Tables (r_pucch %d, bwp %p)\n",r_pucch,bwp); - int rsetindex = *scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_ResourceCommon; + LOG_D(NR_MAC,"pucch_acknak: Filling default PUCCH configuration from Tables (r_pucch %d, pucch_Config %p)\n",r_pucch,pucch_Config); + int rsetindex = *pucch_ConfigCommon->pucch_ResourceCommon; int prb_start, second_hop_prb, nr_of_symb, start_symb; set_r_pucch_parms(rsetindex, r_pucch, @@ -1394,7 +1241,7 @@ void nr_configure_pucch(const NR_SIB1_t *sib1, &start_symb); pucch_pdu->prb_start = prb_start; - pucch_pdu->rnti = rnti; + pucch_pdu->rnti = UE->rnti; pucch_pdu->freq_hop_flag = 1; pucch_pdu->second_hop_prb = second_hop_prb; pucch_pdu->format_type = default_pucch_fmt[rsetindex]; @@ -1436,27 +1283,15 @@ void set_r_pucch_parms(int rsetindex, *start_symbol_index = default_pucch_firstsymb[rsetindex]; } - void prepare_dci(const NR_CellGroupConfig_t *CellGroup, + const NR_UE_DL_BWP_t *current_BWP, + const NR_ControlResourceSet_t *coreset, dci_pdu_rel15_t *dci_pdu_rel15, - nr_dci_format_t format, - int bwp_id) { + nr_dci_format_t format) { AssertFatal(CellGroup!=NULL,"CellGroup shouldn't be null here\n"); - const NR_BWP_DownlinkDedicated_t *bwpd = NULL; - const NR_PDSCH_Config_t *pdsch_Config = NULL; - const NR_PDCCH_Config_t *pdcch_Config = NULL; - - if (bwp_id>0) { - bwpd=CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated; - } - else { - bwpd=CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP; - } - pdsch_Config = (bwpd->pdsch_Config) ? bwpd->pdsch_Config->choice.setup : NULL; - pdcch_Config = (bwpd->pdcch_Config) ? bwpd->pdcch_Config->choice.setup : NULL; - + const NR_PDSCH_Config_t *pdsch_Config = current_BWP ? current_BWP->pdsch_Config : NULL; switch(format) { case NR_UL_DCI_FORMAT_0_1: @@ -1494,7 +1329,7 @@ void prepare_dci(const NR_CellGroupConfig_t *CellGroup, if (pdsch_Config->aperiodic_ZP_CSI_RS_ResourceSetsToAddModList != NULL) AssertFatal(1==0,"Aperiodic ZP CSI-RS currently not supported\n"); // transmission configuration indication - if (pdcch_Config->controlResourceSetToAddModList->list.array[0]->tci_PresentInDCI != NULL) + if (coreset->tci_PresentInDCI != NULL) AssertFatal(1==0,"TCI in DCI currently not supported\n"); //srs resource set if (CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->carrierSwitching!=NULL) { @@ -1518,9 +1353,8 @@ void prepare_dci(const NR_CellGroupConfig_t *CellGroup, else dci_pdu_rel15->srs_request.val = 0; // CBGTI and CBGFI - if (CellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig && - CellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup && - CellGroup->spCellConfig->spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup->codeBlockGroupTransmission != NULL) + if (current_BWP->pdsch_servingcellconfig && + current_BWP->pdsch_servingcellconfig->codeBlockGroupTransmission != NULL) AssertFatal(1==0,"CBG transmission currently not supported\n"); break; default : @@ -1531,23 +1365,28 @@ void prepare_dci(const NR_CellGroupConfig_t *CellGroup, void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, const NR_CellGroupConfig_t *CellGroup, + const NR_UE_DL_BWP_t *current_BWP, nfapi_nr_dl_dci_pdu_t *pdcch_dci_pdu, dci_pdu_rel15_t *dci_pdu_rel15, int dci_format, int rnti_type, int N_RB, int bwp_id, - NR_ControlResourceSetId_t coreset_id, + NR_ControlResourceSet_t *coreset, uint16_t cset0_bwp_size) { uint8_t fsize = 0, pos = 0; uint64_t *dci_pdu = (uint64_t *)pdcch_dci_pdu->Payload; *dci_pdu=0; - int dci_size = nr_dci_size(scc->downlinkConfigCommon->initialDownlinkBWP,scc->uplinkConfigCommon->initialUplinkBWP, CellGroup, dci_pdu_rel15, dci_format, rnti_type, N_RB, bwp_id, coreset_id, cset0_bwp_size); + NR_ControlResourceSetId_t coreset_id = coreset->controlResourceSetId; + int dci_size = nr_dci_size(scc->downlinkConfigCommon->initialDownlinkBWP, + scc->uplinkConfigCommon->initialUplinkBWP, + CellGroup, dci_pdu_rel15, dci_format, + rnti_type, N_RB, bwp_id, coreset_id, cset0_bwp_size); pdcch_dci_pdu->PayloadSizeBits = dci_size; AssertFatal(dci_size <= 64, "DCI sizes above 64 bits not yet supported"); if (dci_format == NR_DL_DCI_FORMAT_1_1 || dci_format == NR_UL_DCI_FORMAT_0_1) - prepare_dci(CellGroup, dci_pdu_rel15, dci_format, bwp_id); + prepare_dci(CellGroup, current_BWP, coreset, dci_pdu_rel15, dci_format); /// Payload generation switch (dci_format) { @@ -2295,30 +2134,12 @@ int get_nrofHARQ_ProcessesForPDSCH(e_NR_PDSCH_ServingCellConfig__nrofHARQ_Proces } } -int get_dl_bwp_id(const NR_ServingCellConfig_t *servingCellConfig) -{ - if (servingCellConfig->firstActiveDownlinkBWP_Id) - return *servingCellConfig->firstActiveDownlinkBWP_Id; - else if (servingCellConfig->defaultDownlinkBWP_Id) - return *servingCellConfig->defaultDownlinkBWP_Id; - else - return 1; -} - -int get_ul_bwp_id(const NR_ServingCellConfig_t *servingCellConfig) -{ - if (servingCellConfig->uplinkConfig && servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id) - return *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id; - else - return 1; -} - /* hack data to remove UE in the phy */ int rnti_to_remove[10]; volatile int rnti_to_remove_count; pthread_mutex_t rnti_to_remove_mutex = PTHREAD_MUTEX_INITIALIZER; -void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr) +void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_allocator_t *uia) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; destroy_nr_list(&sched_ctrl->available_dl_harq); @@ -2327,6 +2148,7 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr) destroy_nr_list(&sched_ctrl->available_ul_harq); destroy_nr_list(&sched_ctrl->feedback_ul_harq); destroy_nr_list(&sched_ctrl->retrans_ul_harq); + uid_linear_allocator_free(uia, UE->uid); LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti); const rnti_t rnti = UE->rnti; free(UE); @@ -2356,6 +2178,253 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr) } } +// main function to configure parameters of current BWP +void configure_UE_BWP(gNB_MAC_INST *nr_mac, + NR_ServingCellConfigCommon_t *scc, + NR_UE_sched_ctrl_t *sched_ctrl, + NR_RA_t *ra, + NR_UE_info_t *UE) { + + AssertFatal((ra != NULL && UE == NULL) || (ra == NULL && UE != NULL), "RA and UE structures are mutually exlusive in BWP configuration\n"); + + NR_CellGroupConfig_t *CellGroup; + NR_UE_DL_BWP_t *DL_BWP; + NR_UE_UL_BWP_t *UL_BWP; + + if (ra) { + DL_BWP = &ra->DL_BWP; + UL_BWP = &ra->UL_BWP; + CellGroup = ra->CellGroup; + } + else { + DL_BWP = &UE->current_DL_BWP; + UL_BWP = &UE->current_UL_BWP; + CellGroup = UE->CellGroup; + } + NR_BWP_Downlink_t *dl_bwp = NULL; + NR_BWP_Uplink_t *ul_bwp = NULL; + NR_BWP_DownlinkDedicated_t *bwpd = NULL; + NR_BWP_UplinkDedicated_t *ubwpd = NULL; + DL_BWP->n_dl_bwp = 1; + UL_BWP->n_ul_bwp = 1; + int old_dl_bwp_id = DL_BWP->bwp_id; + int old_ul_bwp_id = UL_BWP->bwp_id; + + int target_ss; + + if (CellGroup && + CellGroup->spCellConfig && + CellGroup->spCellConfig->spCellConfigDedicated) { + + const NR_ServingCellConfig_t *servingCellConfig = CellGroup->spCellConfig->spCellConfigDedicated; + DL_BWP->pdsch_servingcellconfig = servingCellConfig->pdsch_ServingCellConfig? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL; + target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; + + if(UE && UE->Msg3_dcch_dtch) { + // switching to initial BWP + DL_BWP->bwp_id = 0; + UL_BWP->bwp_id = 0; + UE->Msg3_dcch_dtch = false; + } + else { + // (re)configuring BWP + // TODO BWP switching not via RRC reconfiguration + // via RRC if firstActiveXlinkBWP_Id is NULL, MAC stays on the same BWP as before + if (servingCellConfig->firstActiveDownlinkBWP_Id) + DL_BWP->bwp_id = *servingCellConfig->firstActiveDownlinkBWP_Id; + if (servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id) + UL_BWP->bwp_id = *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id; + } + + const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig->downlinkBWP_ToAddModList; + if(bwpList) + DL_BWP->n_dl_bwp = bwpList->list.count; + if (DL_BWP->bwp_id>0) { + for (int i=0; i<bwpList->list.count; i++) { + dl_bwp = bwpList->list.array[i]; + if(dl_bwp->bwp_Id == DL_BWP->bwp_id) + break; + } + AssertFatal(dl_bwp!=NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n",DL_BWP->bwp_id); + } + + const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList; + if(ubwpList) + UL_BWP->n_ul_bwp = ubwpList->list.count; + if (UL_BWP->bwp_id>0) { + for (int i=0; i<ubwpList->list.count; i++) { + ul_bwp = ubwpList->list.array[i]; + if(ul_bwp->bwp_Id == UL_BWP->bwp_id) + break; + } + AssertFatal(ul_bwp!=NULL,"Couldn't find ULBWP corresponding to BWP ID %ld\n",UL_BWP->bwp_id); + } + + // selection of dedicated BWPs + if(dl_bwp) + bwpd = dl_bwp->bwp_Dedicated; + else + bwpd = servingCellConfig->initialDownlinkBWP; + if(ul_bwp) + ubwpd = ul_bwp->bwp_Dedicated; + else + ubwpd = servingCellConfig->uplinkConfig->initialUplinkBWP; + + DL_BWP->pdsch_Config = bwpd->pdsch_Config->choice.setup; + UL_BWP->pusch_Config = ubwpd->pusch_Config->choice.setup; + UL_BWP->pucch_Config = ubwpd->pucch_Config->choice.setup; + UL_BWP->srs_Config = ubwpd->srs_Config->choice.setup; + UL_BWP->csi_MeasConfig = servingCellConfig->csi_MeasConfig ? servingCellConfig->csi_MeasConfig->choice.setup : NULL; + } + else { + DL_BWP->bwp_id = 0; + DL_BWP->bwp_id = 0; + target_ss = NR_SearchSpace__searchSpaceType_PR_common; + DL_BWP->pdsch_Config = NULL; + UL_BWP->pusch_Config = NULL; + UL_BWP->pucch_Config = NULL; + UL_BWP->csi_MeasConfig = NULL; + } + + if (old_dl_bwp_id != DL_BWP->bwp_id) + LOG_I(NR_MAC, "Switching to DL-BWP %li\n", DL_BWP->bwp_id); + if (old_ul_bwp_id != UL_BWP->bwp_id) + LOG_I(NR_MAC, "Switching to UL-BWP %li\n", UL_BWP->bwp_id); + + // TDA lists + if (DL_BWP->bwp_id>0) + DL_BWP->tdaList = dl_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + else + DL_BWP->tdaList = scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; + + if(UL_BWP->bwp_id>0) + UL_BWP->tdaList = ul_bwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + else + UL_BWP->tdaList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; + + // setting generic parameters + NR_BWP_t dl_genericParameters = (DL_BWP->bwp_id>0 && dl_bwp) ? + dl_bwp->bwp_Common->genericParameters: + scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; + + DL_BWP->scs = dl_genericParameters.subcarrierSpacing; + DL_BWP->cyclicprefix = dl_genericParameters.cyclicPrefix; + DL_BWP->BWPSize = NRRIV2BW(dl_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + DL_BWP->BWPStart = NRRIV2PRBOFFSET(dl_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + NR_BWP_t ul_genericParameters = (UL_BWP->bwp_id>0 && ul_bwp) ? + ul_bwp->bwp_Common->genericParameters: + scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; + + UL_BWP->scs = ul_genericParameters.subcarrierSpacing; + UL_BWP->cyclicprefix = ul_genericParameters.cyclicPrefix; + UL_BWP->BWPSize = NRRIV2BW(ul_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + UL_BWP->BWPStart = NRRIV2PRBOFFSET(ul_genericParameters.locationAndBandwidth, MAX_BWP_SIZE); + + // Set downlink MCS table + if (DL_BWP->pdsch_Config && + DL_BWP->pdsch_Config->mcs_Table) { + if (*DL_BWP->pdsch_Config->mcs_Table == 0) + DL_BWP->mcsTableIdx = 1; + else + DL_BWP->mcsTableIdx = 2; + } else + DL_BWP->mcsTableIdx = 0; + LOG_D(NR_MAC,"DL MCS Table Index: %d\n",DL_BWP->mcsTableIdx); + + if (UL_BWP->pusch_Config == NULL || !UL_BWP->pusch_Config->transformPrecoder) + UL_BWP->transform_precoding = !scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder; + else + UL_BWP->transform_precoding = *UL_BWP->pusch_Config->transformPrecoder; + + if(UL_BWP->bwp_id>0) + UL_BWP->pucch_ConfigCommon = ul_bwp->bwp_Common->pucch_ConfigCommon->choice.setup; + else + UL_BWP->pucch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup; + + + if(UE) { + // setting PDCCH related structures for sched_ctrl + sched_ctrl->search_space = get_searchspace(scc, + bwpd, + target_ss); + sched_ctrl->coreset = get_coreset(nr_mac, + scc, + bwpd, + sched_ctrl->search_space, + target_ss); + + sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac, + sched_ctrl->search_space, + sched_ctrl->coreset, + scc, + &dl_genericParameters, + nr_mac->type0_PDCCH_CSS_config); + + // set DL DCI format + DL_BWP->dci_format = (sched_ctrl->search_space->searchSpaceType && + sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ? + (sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_1_And_1_1 ? + NR_DL_DCI_FORMAT_1_1 : NR_DL_DCI_FORMAT_1_0) : + NR_DL_DCI_FORMAT_1_0; + // set UL DCI format + UL_BWP->dci_format = (sched_ctrl->search_space->searchSpaceType && + sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) ? + (sched_ctrl->search_space->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_1_And_1_1 ? + NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0) : + NR_UL_DCI_FORMAT_0_0; + + if (UL_BWP->csi_MeasConfig) + compute_csi_bitlen (UL_BWP->csi_MeasConfig, UE->csi_report_template); + + } + + if(ra) { + // setting PDCCH related structures for RA + struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = NULL; + NR_SearchSpaceId_t ra_SearchSpace = 0; + if(dl_bwp) { + commonSearchSpaceList = dl_bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + ra_SearchSpace = *dl_bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; + } else { + commonSearchSpaceList = scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + ra_SearchSpace = *scc->downlinkConfigCommon->initialDownlinkBWP->pdcch_ConfigCommon->choice.setup->ra_SearchSpace; + } + AssertFatal(commonSearchSpaceList->list.count > 0, "common SearchSpace list has 0 elements\n"); + for (int i = 0; i < commonSearchSpaceList->list.count; i++) { + NR_SearchSpace_t * ss = commonSearchSpaceList->list.array[i]; + if (ss->searchSpaceId == ra_SearchSpace) + ra->ra_ss = ss; + } + AssertFatal(ra->ra_ss!=NULL,"SearchSpace cannot be null for RA\n"); + + ra->coreset = get_coreset(nr_mac, scc, dl_bwp, ra->ra_ss, NR_SearchSpace__searchSpaceType_PR_common); + ra->sched_pdcch = set_pdcch_structure(nr_mac, + ra->ra_ss, + ra->coreset, + scc, + &dl_genericParameters, + &nr_mac->type0_PDCCH_CSS_config[ra->beam_id]); + + UL_BWP->dci_format = NR_UL_DCI_FORMAT_0_0; + DL_BWP->dci_format = NR_DL_DCI_FORMAT_1_0; + } + + // Set uplink MCS table + long *mcs_Table = NULL; + if (UL_BWP->pusch_Config) + mcs_Table = UL_BWP->transform_precoding ? + UL_BWP->pusch_Config->mcs_Table : + UL_BWP->pusch_Config->mcs_TableTransformPrecoder; + + UL_BWP->mcs_table = get_pusch_mcs_table(mcs_Table, + UL_BWP->transform_precoding ? 0 : 1, + UL_BWP->dci_format, + NR_RNTI_C, + target_ss, + false); +} + //------------------------------------------------------------------------------ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup) { @@ -2374,6 +2443,7 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf } UE->rnti = rntiP; + UE->uid = uid_linear_allocator_new(&UE_info->uid_allocator); UE->CellGroup = CellGroup; if (CellGroup) @@ -2381,95 +2451,53 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf else UE->Msg4_ACKed = false; - if (CellGroup && - CellGroup->spCellConfig && - CellGroup->spCellConfig->spCellConfigDedicated && - CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig && - CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) { - compute_csi_bitlen(CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE); - } - - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - memset(sched_ctrl, 0, sizeof(*sched_ctrl)); - sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */ - sched_ctrl->set_pmi = false; - sched_ctrl->ta_frame = 0; - sched_ctrl->ta_update = 31; - sched_ctrl->ta_apply = false; - sched_ctrl->ul_rssi = 0; - sched_ctrl->pucch_consecutive_dtx_cnt = 0; - sched_ctrl->pusch_consecutive_dtx_cnt = 0; - sched_ctrl->ul_failure = 0; - sched_ctrl->sched_srs.frame = -1; - sched_ctrl->sched_srs.slot = -1; - sched_ctrl->sched_srs.srs_scheduled = false; - - /* set illegal time domain allocation to force recomputation of all fields */ - sched_ctrl->pdsch_semi_static.time_domain_allocation = -1; - sched_ctrl->pusch_semi_static.time_domain_allocation = -1; - const NR_ServingCellConfig_t *servingCellConfig = CellGroup && CellGroup->spCellConfig ? CellGroup->spCellConfig->spCellConfigDedicated : NULL; + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + memset(sched_ctrl, 0, sizeof(*sched_ctrl)); + sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */ + sched_ctrl->ta_update = 31; + sched_ctrl->sched_srs.frame = -1; + sched_ctrl->sched_srs.slot = -1; + + // initialize UE BWP information + NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; + memset(dl_bwp, 0, sizeof(*dl_bwp)); + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + memset(ul_bwp, 0, sizeof(*ul_bwp)); + configure_UE_BWP(nr_mac, scc, sched_ctrl, NULL, UE); + + /* set illegal time domain allocation to force recomputation of all fields */ + sched_ctrl->pdsch_semi_static.time_domain_allocation = -1; + sched_ctrl->pusch_semi_static.time_domain_allocation = -1; /* Set default BWPs */ - const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = servingCellConfig ? servingCellConfig->downlinkBWP_ToAddModList : NULL; - - const int bwp_id = servingCellConfig ? *servingCellConfig->firstActiveDownlinkBWP_Id : 0; - sched_ctrl->active_bwp = bwpList && bwp_id > 0 ? bwpList->list.array[bwp_id - 1] : NULL; - NR_BWP_t *genericParameters = sched_ctrl->active_bwp ? - &sched_ctrl->active_bwp->bwp_Common->genericParameters: - &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - const int target_ss = sched_ctrl->active_bwp ? NR_SearchSpace__searchSpaceType_PR_ue_Specific : NR_SearchSpace__searchSpaceType_PR_common; - const NR_SIB1_t *sib1 = nr_mac->common_channels[0].sib1 ? nr_mac->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - sched_ctrl->search_space = get_searchspace(sib1, - scc, - sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, - target_ss); - sched_ctrl->coreset = get_coreset(nr_mac, - scc, - sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Dedicated : NULL, - sched_ctrl->search_space, - target_ss); - sched_ctrl->sched_pdcch = set_pdcch_structure(nr_mac, - sched_ctrl->search_space, - sched_ctrl->coreset, - scc, - genericParameters, - NULL); - sched_ctrl->next_dl_bwp_id = -1; - sched_ctrl->next_ul_bwp_id = -1; - const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = servingCellConfig ? servingCellConfig->uplinkConfig->uplinkBWP_ToAddModList : NULL; - if (ubwpList) - AssertFatal(ubwpList->list.count <= NR_MAX_NUM_BWP, - "uplinkBWP_ToAddModList has %d BWP!\n", - ubwpList->list.count); - const int ul_bwp_id = servingCellConfig ? *servingCellConfig->uplinkConfig->firstActiveUplinkBWP_Id : 0; - sched_ctrl->active_ubwp = ubwpList && ul_bwp_id > 0 ? ubwpList->list.array[ul_bwp_id - 1] : NULL; - - /* get Number of HARQ processes for this UE */ - if (servingCellConfig) - AssertFatal(servingCellConfig->pdsch_ServingCellConfig->present == NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup, - "no pdsch-ServingCellConfig found for UE %04x\n", - UE->rnti); - const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL; - // pdsch == NULL in SA -> will create default (8) number of HARQ processes - create_dl_harq_list(sched_ctrl, pdsch); - // add all available UL HARQ processes for this UE - // nb of ul harq processes not configurable - create_nr_list(&sched_ctrl->available_ul_harq, 16); - for (int harq = 0; harq < 16; harq++) - add_tail_nr_list(&sched_ctrl->available_ul_harq, harq); - create_nr_list(&sched_ctrl->feedback_ul_harq, 16); - create_nr_list(&sched_ctrl->retrans_ul_harq, 16); + sched_ctrl->next_dl_bwp_id = -1; + sched_ctrl->next_ul_bwp_id = -1; + AssertFatal(ul_bwp->n_ul_bwp <= NR_MAX_NUM_BWP, + "uplinkBWP_ToAddModList has %d BWP!\n", + ul_bwp->n_ul_bwp); + + /* get Number of HARQ processes for this UE */ + // pdsch_servingcellconfig == NULL in SA -> will create default (8) number of HARQ processes + create_dl_harq_list(sched_ctrl, dl_bwp->pdsch_servingcellconfig); + // add all available UL HARQ processes for this UE + // nb of ul harq processes not configurable + create_nr_list(&sched_ctrl->available_ul_harq, 16); + for (int harq = 0; harq < 16; harq++) + add_tail_nr_list(&sched_ctrl->available_ul_harq, harq); + create_nr_list(&sched_ctrl->feedback_ul_harq, 16); + create_nr_list(&sched_ctrl->retrans_ul_harq, 16); pthread_mutex_lock(&UE_info->mutex); int i; - for(i=0; i<MAX_MOBILES_PER_GNB; i++) + for(i=0; i<MAX_MOBILES_PER_GNB; i++) { if (UE_info->list[i] == NULL) { UE_info->list[i] = UE; break; } + } if (i == MAX_MOBILES_PER_GNB) { LOG_E(NR_MAC,"Try to add UE %04x but the list is full\n", rntiP); - delete_nr_ue_data(UE, nr_mac->common_channels); + delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator); pthread_mutex_unlock(&UE_info->mutex); return NULL; } @@ -2573,7 +2601,7 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti) memcpy(UE_info->list, newUEs, sizeof(UE_info->list)); pthread_mutex_unlock(&UE_info->mutex); - delete_nr_ue_data(UE, nr_mac->common_channels); + delete_nr_ue_data(UE, nr_mac->common_channels, &UE_info->uid_allocator); } void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti) { @@ -2597,46 +2625,12 @@ uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) { } -void get_pdsch_to_harq_feedback(NR_UE_info_t *UE, - int bwp_id, - NR_SearchSpace__searchSpaceType_PR ss_type, +void get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config, + nr_dci_format_t dci_format, int *max_fb_time, uint8_t *pdsch_to_harq_feedback) { - NR_CellGroupConfig_t *CellGroup = UE->CellGroup; - NR_BWP_DownlinkDedicated_t *bwpd=NULL; - NR_BWP_UplinkDedicated_t *ubwpd=NULL; - - if (ss_type == NR_SearchSpace__searchSpaceType_PR_ue_Specific) { - AssertFatal(CellGroup!=NULL,"Cellgroup is not defined for UE %04x\n",UE->rnti); - AssertFatal(CellGroup->spCellConfig!=NULL,"Cellgroup->spCellConfig is null\n"); - AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated!=NULL,"CellGroup->spCellConfig->spCellConfigDedicated is null\n"); - } - if (bwp_id>0) { - AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList!=NULL, - "CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList is null\n"); - AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList!=NULL, - "CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList is null\n"); - AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count >= bwp_id, - "CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count %d < bwp_id %d\n", - CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count,bwp_id); - AssertFatal(CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count >= bwp_id, - "CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count %d < bwp_id %d\n", - CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count,bwp_id); - - bwpd = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated; - ubwpd = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[bwp_id-1]->bwp_Dedicated; - } - else if (CellGroup && CellGroup->spCellConfig && CellGroup->spCellConfig->spCellConfigDedicated) { // this is an initialBWP - AssertFatal((bwpd=CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)!=NULL, - "CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP is null\n"); - AssertFatal((ubwpd=CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP)!=NULL, - "CellGroup->spCellConfig->spCellConfigDedicated->uplnikConfig->initialUplinkBWP is null\n"); - } - NR_SearchSpace_t *ss=NULL; - - // common search type uses DCI format 1_0 - if (ss_type == NR_SearchSpace__searchSpaceType_PR_common) { + if (dci_format == NR_DL_DCI_FORMAT_1_0) { for (int i=0; i<8; i++) { pdsch_to_harq_feedback[i] = i+1; if(pdsch_to_harq_feedback[i]>*max_fb_time) @@ -2644,42 +2638,16 @@ void get_pdsch_to_harq_feedback(NR_UE_info_t *UE, } } else { - - // searching for a ue specific search space - int found=0; - AssertFatal(bwpd->pdcch_Config!=NULL,"bwpd->pdcch_Config is null\n"); - AssertFatal(bwpd->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL, - "bwpd->pdcch_Config->choice.setup->searchSpacesToAddModList is null\n"); - for (int i=0;i<bwpd->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count;i++) { - ss=bwpd->pdcch_Config->choice.setup->searchSpacesToAddModList->list.array[i]; - AssertFatal(ss->controlResourceSetId != NULL,"ss->controlResourceSetId is null\n"); - AssertFatal(ss->searchSpaceType != NULL,"ss->searchSpaceType is null\n"); - if (ss->searchSpaceType->present == ss_type) { - found=1; - break; - } - } - AssertFatal(found==1,"Couldn't find a ue specific searchspace\n"); - - if (ss->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_0_And_1_0) { + AssertFatal(pucch_Config!=NULL,"pucch_Config shouldn't be null here\n"); + if(pucch_Config->dl_DataToUL_ACK != NULL) { for (int i=0; i<8; i++) { - pdsch_to_harq_feedback[i] = i+1; + pdsch_to_harq_feedback[i] = *pucch_Config->dl_DataToUL_ACK->list.array[i]; if(pdsch_to_harq_feedback[i]>*max_fb_time) *max_fb_time = pdsch_to_harq_feedback[i]; } } - else { - AssertFatal(ubwpd!=NULL,"ubwpd shouldn't be null here\n"); - if(ubwpd->pucch_Config->choice.setup->dl_DataToUL_ACK != NULL) { - for (int i=0; i<8; i++) { - pdsch_to_harq_feedback[i] = *ubwpd->pucch_Config->choice.setup->dl_DataToUL_ACK->list.array[i]; - if(pdsch_to_harq_feedback[i]>*max_fb_time) - *max_fb_time = pdsch_to_harq_feedback[i]; - } - } - else - AssertFatal(0==1,"There is no allocated dl_DataToUL_ACK for pdsch to harq feedback\n"); - } + else + AssertFatal(0==1,"There is no allocated dl_DataToUL_ACK for pdsch to harq feedback\n"); } } @@ -2701,12 +2669,13 @@ void nr_csirs_scheduling(int Mod_idP, if (sched_ctrl->rrc_processing_timer > 0) { continue; } - NR_CellGroupConfig_t *CellGroup = UE->CellGroup; - if (!CellGroup || !CellGroup->spCellConfig || !CellGroup->spCellConfig->spCellConfigDedicated || - !CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig) continue; + NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + + if (!ul_bwp->csi_MeasConfig) continue; - NR_CSI_MeasConfig_t *csi_measconfig = CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + NR_CSI_MeasConfig_t *csi_measconfig = ul_bwp->csi_MeasConfig; if (csi_measconfig->nzp_CSI_RS_ResourceToAddModList != NULL) { @@ -2714,9 +2683,6 @@ void nr_csirs_scheduling(int Mod_idP, int period, offset; nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body; - NR_BWP_t *genericParameters = sched_ctrl->active_bwp ? - &sched_ctrl->active_bwp->bwp_Common->genericParameters : - &gNB_mac->common_channels[0].ServingCellConfigCommon->downlinkConfigCommon->initialDownlinkBWP->genericParameters; for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){ nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id]; @@ -2735,22 +2701,20 @@ void nr_csirs_scheduling(int Mod_idP, nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csirs_pdu_rel15 = &dl_tti_csirs_pdu->csi_rs_pdu.csi_rs_pdu_rel15; - csirs_pdu_rel15->subcarrier_spacing = genericParameters->subcarrierSpacing; - if (genericParameters->cyclicPrefix) - csirs_pdu_rel15->cyclic_prefix = *genericParameters->cyclicPrefix; + csirs_pdu_rel15->subcarrier_spacing = dl_bwp->scs; + if (dl_bwp->cyclicprefix) + csirs_pdu_rel15->cyclic_prefix = *dl_bwp->cyclicprefix; else csirs_pdu_rel15->cyclic_prefix = 0; // According to last paragraph of TS 38.214 5.2.2.3.1 - uint16_t BWPSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - uint16_t BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - if (resourceMapping.freqBand.startingRB < BWPStart) { - csirs_pdu_rel15->start_rb = BWPStart; + if (resourceMapping.freqBand.startingRB < dl_bwp->BWPStart) { + csirs_pdu_rel15->start_rb = dl_bwp->BWPStart; } else { csirs_pdu_rel15->start_rb = resourceMapping.freqBand.startingRB; } - if (resourceMapping.freqBand.nrofRBs > (BWPStart + BWPSize - csirs_pdu_rel15->start_rb)) { - csirs_pdu_rel15->nr_of_rbs = BWPStart + BWPSize - csirs_pdu_rel15->start_rb; + if (resourceMapping.freqBand.nrofRBs > (dl_bwp->BWPStart + dl_bwp->BWPSize - csirs_pdu_rel15->start_rb)) { + csirs_pdu_rel15->nr_of_rbs = dl_bwp->BWPStart + dl_bwp->BWPSize - csirs_pdu_rel15->start_rb; } else { csirs_pdu_rel15->nr_of_rbs = resourceMapping.freqBand.nrofRBs; } @@ -2905,8 +2869,8 @@ void nr_csirs_scheduling(int Mod_idP, void nr_mac_update_timers(module_id_t module_id, frame_t frame, sub_frame_t slot) { - NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info; + NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info; UE_iterator(UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; if (sched_ctrl->rrc_processing_timer > 0) { @@ -2914,8 +2878,6 @@ void nr_mac_update_timers(module_id_t module_id, if (sched_ctrl->rrc_processing_timer == 0) { LOG_I(NR_MAC, "(%d.%d) De-activating RRC processing timer for UE %04x\n", frame, slot, UE->rnti); - const NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1 ? RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - NR_CellGroupConfig_t *cg = NULL; uper_decode(NULL, &asn_DEF_NR_CellGroupConfig, //might be added prefix later @@ -2929,121 +2891,37 @@ void nr_mac_update_timers(module_id_t module_id, } NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[0].ServingCellConfigCommon; - const NR_ServingCellConfig_t *spCellConfigDedicated = cg && cg->spCellConfig ? cg->spCellConfig->spCellConfigDedicated : NULL; LOG_I(NR_MAC,"Modified rnti %04x with CellGroup\n", UE->rnti); process_CellGroup(cg,&UE->UE_sched_ctrl); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - const NR_PDSCH_ServingCellConfig_t *pdsch = spCellConfigDedicated ? spCellConfigDedicated->pdsch_ServingCellConfig->choice.setup : NULL; + configure_UE_BWP(RC.nrmac[module_id], scc, sched_ctrl, NULL, UE); + if (get_softmodem_params()->sa) { // add all available DL HARQ processes for this UE in SA - create_dl_harq_list(sched_ctrl, pdsch); - } - - // If needed, update the Dedicated BWP - const int current_bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0; - const int current_ubwp_id = sched_ctrl->active_ubwp ? sched_ctrl->active_ubwp->bwp_Id : 0; - if (UE->Msg3_dcch_dtch) { - // 3GPP TS 38.321 Section 5.15 Bandwidth Part (BWP) operation - // Currently there are no PRACH occasions configured for any Dedicated BWP, so UE will switch to the initialDownlinkBWP - sched_ctrl->active_bwp = NULL; - if (current_bwp_id != 0) { - LOG_I(NR_MAC, "(%d.%d) Switching to initialDownlinkBWP\n", frame, slot); - } - // 3GPP TS 38.321 Section 5.15 Bandwidth Part (BWP) operation - // Currently there are no PRACH occasions configured for any Dedicated BWP, so UE will switch to the initialUplinkBWP - sched_ctrl->active_ubwp = NULL; - if (current_ubwp_id != 0) { - LOG_I(NR_MAC, "(%d.%d) Switching to initialUplinkBWP\n", frame, slot); - } - UE->Msg3_dcch_dtch = false; - } else if (spCellConfigDedicated && - spCellConfigDedicated->downlinkBWP_ToAddModList && - spCellConfigDedicated->uplinkConfig && - spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList) { - sched_ctrl->active_bwp = spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[*spCellConfigDedicated->firstActiveDownlinkBWP_Id - 1]; - if (*spCellConfigDedicated->firstActiveDownlinkBWP_Id != current_bwp_id) { - LOG_I(NR_MAC, "(%d.%d) Switching to DL-BWP %li\n", frame, slot, sched_ctrl->active_bwp->bwp_Id); - } - sched_ctrl->active_ubwp = spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[*spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id - 1]; - if (*spCellConfigDedicated->uplinkConfig->firstActiveUplinkBWP_Id != current_ubwp_id) { - LOG_I(NR_MAC, "(%d.%d) Switching to UL-BWP %li\n", frame, slot, sched_ctrl->active_ubwp->bwp_Id); - } - } - - // Update coreset/searchspace - NR_BWP_Downlink_t *bwp = sched_ctrl->active_bwp; - NR_BWP_DownlinkDedicated_t *bwpd = NULL; - NR_BWP_t *genericParameters = NULL; - int target_ss = NR_SearchSpace__searchSpaceType_PR_common; - if (bwp) { - target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - bwpd = sched_ctrl->active_bwp->bwp_Dedicated; - genericParameters = &sched_ctrl->active_bwp->bwp_Common->genericParameters; - } else if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - (cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)) { - target_ss = NR_SearchSpace__searchSpaceType_PR_ue_Specific; - bwpd = cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP; - genericParameters = &scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters; - } - sched_ctrl->search_space = get_searchspace(sib1, scc, (void*)bwpd, target_ss); - sched_ctrl->coreset = get_coreset(RC.nrmac[module_id], scc, (void*)bwpd, sched_ctrl->search_space, target_ss); - sched_ctrl->sched_pdcch = set_pdcch_structure(RC.nrmac[module_id], - sched_ctrl->search_space, - sched_ctrl->coreset, - scc, - genericParameters, - RC.nrmac[module_id]->type0_PDCCH_CSS_config); - sched_ctrl->maxL = 2; - if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig && - cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) { - compute_csi_bitlen (cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE); + create_dl_harq_list(sched_ctrl, UE->current_DL_BWP.pdsch_servingcellconfig); } NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static; const uint8_t layers = set_dl_nrOfLayers(sched_ctrl); const int tda = get_dl_tda(RC.nrmac[module_id], scc, slot); - nr_set_pdsch_semi_static(sib1, + nr_set_pdsch_semi_static(&UE->current_DL_BWP, scc, - cg, - bwp, - bwpd, tda, layers, sched_ctrl, ps); - NR_BWP_Uplink_t *ubwp = sched_ctrl->active_ubwp; - NR_BWP_UplinkDedicated_t *ubwpd = NULL; - if (ubwp) { - ubwpd = sched_ctrl->active_ubwp->bwp_Dedicated; - } else if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - (cg->spCellConfig->spCellConfigDedicated->initialDownlinkBWP)) { - ubwpd = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; - } NR_pusch_semi_static_t *ups = &sched_ctrl->pusch_semi_static; - int dci_format = get_dci_format(sched_ctrl); - const uint8_t num_dmrs_cdm_grps_no_data = (ubwp || ubwpd) ? 1 : 2; const uint8_t nrOfLayers = 1; const int utda = get_ul_tda(RC.nrmac[module_id], scc, slot); - nr_set_pusch_semi_static(sib1, + nr_set_pusch_semi_static(&UE->current_UL_BWP, scc, - ubwp, - ubwpd, - dci_format, utda, - num_dmrs_cdm_grps_no_data, nrOfLayers, ups); } @@ -3063,14 +2941,95 @@ void schedule_nr_bwp_switch(module_id_t module_id, UE_iterator(UE_info->list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - if (sched_ctrl->rrc_processing_timer == 0 && - UE->Msg4_ACKed && - ((sched_ctrl->next_dl_bwp_id >= 0 && sched_ctrl->active_bwp && sched_ctrl->active_bwp->bwp_Id != sched_ctrl->next_dl_bwp_id) || - (sched_ctrl->next_ul_bwp_id >= 0 && sched_ctrl->active_ubwp && sched_ctrl->active_ubwp->bwp_Id != sched_ctrl->next_ul_bwp_id))) { - - LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from dl_bwp_id %ld to %ld and from ul_bwp_id %ld to %ld\n", - frame, slot, UE->rnti, sched_ctrl->active_bwp->bwp_Id, sched_ctrl->next_dl_bwp_id, sched_ctrl->active_ubwp->bwp_Id, sched_ctrl->next_ul_bwp_id); - nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id); + NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + if (sched_ctrl->rrc_processing_timer == 0 && UE->Msg4_ACKed && sched_ctrl->next_dl_bwp_id >= 0) { + + int schedule_bwp_switching = false; + if (dl_bwp->bwp_id == 0) { + // Switching from Initial BWP to Dedicated BWP + if (sched_ctrl->next_dl_bwp_id > 0 && sched_ctrl->next_ul_bwp_id > 0) { + schedule_bwp_switching = true; + LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from Initial DL BWP to %ld and from Initial UL BWP to %ld\n", + frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id); + } + } else if (dl_bwp->bwp_id != sched_ctrl->next_dl_bwp_id && ul_bwp->bwp_id != sched_ctrl->next_ul_bwp_id) { + // Switching between Dedicated BWPs + schedule_bwp_switching = true; + LOG_W(NR_MAC,"%4d.%2d UE %04x Schedule BWP switch from dl_bwp_id %ld to %ld and from ul_bwp_id %ld to %ld\n", + frame, slot, UE->rnti, dl_bwp->bwp_id, sched_ctrl->next_dl_bwp_id, ul_bwp->bwp_id, sched_ctrl->next_ul_bwp_id); + } + + if (schedule_bwp_switching) { + AssertFatal(sched_ctrl->next_dl_bwp_id > 0 && sched_ctrl->next_ul_bwp_id > 0, "BWP switching from a Dedicated BWP to the Initial BWP not handled yet!"); + nr_mac_rrc_bwp_switch_req(module_id, frame, slot, UE->rnti, sched_ctrl->next_dl_bwp_id, sched_ctrl->next_ul_bwp_id); + } } } } + +void UL_tti_req_ahead_initialization(gNB_MAC_INST * gNB, NR_ServingCellConfigCommon_t *scc, int n, int CCid) { + + if(gNB->UL_tti_req_ahead[CCid]) return; + + gNB->UL_tti_req_ahead[CCid] = calloc(n, sizeof(nfapi_nr_ul_tti_request_t)); + AssertFatal(gNB->UL_tti_req_ahead[CCid], + "could not allocate memory for RC.nrmac[]->UL_tti_req_ahead[]\n"); + /* fill in slot/frame numbers: slot is fixed, frame will be updated by scheduler + * consider that scheduler runs sl_ahead: the first sl_ahead slots are + * already "in the past" and thus we put frame 1 instead of 0! */ + for (int i = 0; i < n; ++i) { + nfapi_nr_ul_tti_request_t *req = &gNB->UL_tti_req_ahead[CCid][i]; + req->SFN = i < (gNB->if_inst->sl_ahead-1); + req->Slot = i; + } +} + +void send_initial_ul_rrc_message(module_id_t module_id, + int CC_id, + const NR_UE_info_t *UE, + rb_id_t srb_id, + const uint8_t *sdu, + sdu_size_t sdu_len) { + const gNB_MAC_INST *mac = RC.nrmac[module_id]; + const rnti_t rnti = UE->rnti; + LOG_W(MAC, + "[RAPROC] Received SDU for CCCH on SRB %ld length %d for UE %04x\n", + srb_id, sdu_len, rnti); + + /* TODO REMOVE_DU_RRC: the RRC in the DU is a hack and should be taken out in the future */ + if (NODE_IS_DU(RC.nrrrc[module_id]->node_type)) { + struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[module_id]); + ue_context_p->ue_id_rnti = rnti; + ue_context_p->ue_context.rnti = rnti; + ue_context_p->ue_context.random_ue_identity = rnti; + ue_context_p->ue_context.Srb0.Active = 1; + RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[module_id]->rrc_ue_head, ue_context_p); + } + + const NR_ServingCellConfigCommon_t *scc = RC.nrrrc[module_id]->carrier.servingcellconfigcommon; + const NR_ServingCellConfig_t *sccd = RC.nrrrc[module_id]->configuration.scd; + NR_CellGroupConfig_t cellGroupConfig = {0}; + fill_initial_cellGroupConfig(UE->uid, &cellGroupConfig, scc, sccd, &RC.nrrrc[module_id]->configuration); + + uint8_t du2cu_rrc_container[1024]; + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, + NULL, + &cellGroupConfig, + du2cu_rrc_container, + sizeof(du2cu_rrc_container)); + AssertFatal(enc_rval.encoded > 0, + "Could not encode cellGroupConfig for UE %04x, failed element %s\n", + rnti, + enc_rval.failed_type->name); + + const f1ap_initial_ul_rrc_message_t ul_rrc_msg = { + /* TODO: add mcc, mnc, cell_id, ..., is not available at MAC yet */ + .crnti = rnti, + .rrc_container = (uint8_t *) sdu, + .rrc_container_length = sdu_len, + .du2cu_rrc_container = (uint8_t *) du2cu_rrc_container, + .du2cu_rrc_container_length = (enc_rval.encoded + 7) / 8 + }; + mac->mac_rrc.initial_ul_rrc_message_transfer(module_id, &ul_rrc_msg); +} diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c index c156ebf36dbce6087575eb5963edc309a8c16c2e..97e5f75e340ed248d35f3afc6513e9dd3240f65c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_srs.c @@ -36,19 +36,13 @@ extern RAN_CONTEXT_t RC; void nr_configure_srs(nfapi_nr_srs_pdu_t *srs_pdu, int module_id, int CC_id,NR_UE_info_t* UE, NR_SRS_Resource_t *srs_resource) { - gNB_MAC_INST *nrmac = RC.nrmac[module_id]; - NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon; - NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - - NR_BWP_t ubwp = sched_ctrl->active_ubwp ? - sched_ctrl->active_ubwp->bwp_Common->genericParameters : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; srs_pdu->rnti = UE->rnti; srs_pdu->handle = 0; - srs_pdu->bwp_size = NRRIV2BW(ubwp.locationAndBandwidth, MAX_BWP_SIZE);; - srs_pdu->bwp_start = NRRIV2PRBOFFSET(ubwp.locationAndBandwidth, MAX_BWP_SIZE);; - srs_pdu->subcarrier_spacing = ubwp.subcarrierSpacing; + srs_pdu->bwp_size = current_BWP->BWPSize; + srs_pdu->bwp_start = current_BWP->BWPStart; + srs_pdu->subcarrier_spacing = current_BWP->scs; srs_pdu->cyclic_prefix = 0; srs_pdu->num_ant_ports = srs_resource->nrofSRS_Ports; srs_pdu->num_symbols = srs_resource->resourceMapping.nrofSymbols; @@ -114,28 +108,21 @@ void nr_schedule_srs(int module_id, frame_t frame) { UE_iterator(UE_info->list, UE) { const int CC_id = 0; - NR_ServingCellConfigCommon_t *scc = RC.nrmac[module_id]->common_channels[CC_id].ServingCellConfigCommon; - NR_CellGroupConfig_t *cg = UE->CellGroup; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; sched_ctrl->sched_srs.frame = -1; sched_ctrl->sched_srs.slot = -1; sched_ctrl->sched_srs.srs_scheduled = false; - if(!UE->Msg4_ACKed || sched_ctrl->rrc_processing_timer > 0) { + if((sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) || + sched_ctrl->rrc_processing_timer > 0) { continue; } - NR_SRS_Config_t *srs_config = NULL; - if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { - srs_config = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config->choice.setup; - } else { + NR_SRS_Config_t *srs_config = current_BWP->srs_Config; + if (!srs_config) continue; - } for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) { @@ -163,14 +150,9 @@ void nr_schedule_srs(int module_id, frame_t frame) { continue; } - NR_BWP_t ubwp = sched_ctrl->active_ubwp ? - sched_ctrl->active_ubwp->bwp_Common->genericParameters : - scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - uint16_t period = srs_period[srs_resource->resourceType.choice.periodic->periodicityAndOffset_p.present]; uint16_t offset = get_nr_srs_offset(srs_resource->resourceType.choice.periodic->periodicityAndOffset_p); - - int n_slots_frame = nr_slots_per_frame[ubwp.subcarrierSpacing]; + int n_slots_frame = nr_slots_per_frame[current_BWP->scs]; // Check if UE will transmit the SRS in this frame if ( ((frame - offset/n_slots_frame)*n_slots_frame)%period == 0) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c index d64b9c43db95e9ddde7959036210087594fdbf80..68900cda354cc4e71275ba181d82e7e1a1847c81 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c @@ -80,23 +80,13 @@ static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac, pucch->resource_indicator); NR_COMMON_channels_t * common_ch=nrmac->common_channels; NR_ServingCellConfigCommon_t *scc = common_ch->ServingCellConfigCommon; - NR_CellGroupConfig_t *cg=UE->CellGroup; - NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; + LOG_D(NR_MAC,"%4d.%2d Calling nr_configure_pucch (pucch_Config %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n", + frame,slot,UE->current_UL_BWP.pucch_Config,pucch->r_pucch,pucch->frame,pucch->ul_slot); - LOG_D(NR_MAC,"%4d.%2d Calling nr_configure_pucch (ubwpd %p,r_pucch %d) pucch to be scheduled in %4d.%2d\n", - frame,slot,ubwpd,pucch->r_pucch,pucch->frame,pucch->ul_slot); - - const NR_SIB1_t *sib1 = common_ch->sib1 ? common_ch->sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - nr_configure_pucch(sib1, - pucch_pdu, + nr_configure_pucch(pucch_pdu, scc, - UE->CellGroup, - UE->UE_sched_ctrl.active_ubwp, - ubwpd, - UE->rnti, + UE, pucch->resource_indicator, pucch->csi_bits, pucch->dai_c, @@ -169,560 +159,22 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac, } } - -//! Calculating number of bits set -uint8_t number_of_bits_set (uint8_t buf){ - uint8_t nb_of_bits_set = 0; - uint8_t mask = 0xff; - uint8_t index = 0; - - for (index=7; (buf & mask) && (index>=0) ; index--){ - if (buf & (1<<index)) - nb_of_bits_set++; - - mask>>=1; - } - return nb_of_bits_set; -} - - -void compute_rsrp_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, - uint8_t nb_resources, - nr_csi_report_t *csi_report) { - - if (NR_CSI_ReportConfig__groupBasedBeamReporting_PR_disabled == csi_reportconfig->groupBasedBeamReporting.present) { - if (NULL != csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS) - csi_report->CSI_report_bitlen.nb_ssbri_cri = *(csi_reportconfig->groupBasedBeamReporting.choice.disabled->nrofReportedRS)+1; - else - /*! From Spec 38.331 - * nrofReportedRS - * The number (N) of measured RS resources to be reported per report setting in a non-group-based report. N <= N_max, where N_max is either 2 or 4 depending on UE - * capability. FFS: The signaling mechanism for the gNB to select a subset of N beams for the UE to measure and report. - * When the field is absent the UE applies the value 1 - */ - csi_report->CSI_report_bitlen.nb_ssbri_cri= 1; - } else - csi_report->CSI_report_bitlen.nb_ssbri_cri= 2; - - if (nb_resources) { - csi_report->CSI_report_bitlen.cri_ssbri_bitlen =ceil(log2 (nb_resources)); - csi_report->CSI_report_bitlen.rsrp_bitlen = 7; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP - csi_report->CSI_report_bitlen.diff_rsrp_bitlen =4; //From spec 38.212 Table 6.3.1.1.2-6: CRI, SSBRI, and RSRP - } else { - csi_report->CSI_report_bitlen.cri_ssbri_bitlen =0; - csi_report->CSI_report_bitlen.rsrp_bitlen = 0; - csi_report->CSI_report_bitlen.diff_rsrp_bitlen =0; - } -} - - -uint8_t compute_ri_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, - nr_csi_report_t *csi_report){ - - struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; - uint8_t nb_allowed_ri, ri_bitlen; - uint8_t ri_restriction = 0; - - if (codebookConfig == NULL) { - csi_report->csi_meas_bitlen.ri_bitlen=0; - return ri_restriction; - } - - // codebook type1 single panel - if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present){ - struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel; - if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two){ - - ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; - - nb_allowed_ri = number_of_bits_set(ri_restriction); - ri_bitlen = ceil(log2(nb_allowed_ri)); - - ri_bitlen = ri_bitlen<1?ri_bitlen:1; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel - csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; - } - if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo){ - if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present == - NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) { - // 4 ports - - ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; - - nb_allowed_ri = number_of_bits_set(ri_restriction); - ri_bitlen = ceil(log2(nb_allowed_ri)); - - ri_bitlen = ri_bitlen<2?ri_bitlen:2; //from the spec 38.212 and table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel - csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; - } - else { - // more than 4 ports - - ri_restriction = csi_reportconfig->codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->typeI_SinglePanel_ri_Restriction.buf[0]; - - nb_allowed_ri = number_of_bits_set(ri_restriction); - ri_bitlen = ceil(log2(nb_allowed_ri)); - - csi_report->csi_meas_bitlen.ri_bitlen=ri_bitlen; - } - } - return ri_restriction; - } - else - AssertFatal(1==0,"Other configurations not yet implemented\n"); - return -1; -} - -void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, - uint8_t ri_restriction, - nr_csi_report_t *csi_report){ - - struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; - for(int i=0; i<8; i++) { - if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0) - csi_report->csi_meas_bitlen.li_bitlen[i]=0; - else { - // codebook type1 single panel - if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel==codebookConfig->codebookType.choice.type1->subType.present) - csi_report->csi_meas_bitlen.li_bitlen[i]=ceil(log2(i+1))<2?ceil(log2(i+1)):2; - else - AssertFatal(1==0,"Other configurations not yet implemented\n"); - } - } -} - -void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2, - struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo) { - - // Table 5.2.2.2.1-2 in 38.214 for supported configurations - switch(morethantwo->n1_n2.present){ - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction): - *n1 = 2; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_two_TypeI_SinglePanel_Restriction): - *n1 = 2; - *n2 = 2; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_one_TypeI_SinglePanel_Restriction): - *n1 = 4; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_three_two_TypeI_SinglePanel_Restriction): - *n1 = 3; - *n2 = 2; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_one_TypeI_SinglePanel_Restriction): - *n1 = 6; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_two_TypeI_SinglePanel_Restriction): - *n1 = 4; - *n2 = 2; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_one_TypeI_SinglePanel_Restriction): - *n1 = 8; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_three_TypeI_SinglePanel_Restriction): - *n1 = 4; - *n2 = 3; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_six_two_TypeI_SinglePanel_Restriction): - *n1 = 4; - *n2 = 2; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_twelve_one_TypeI_SinglePanel_Restriction): - *n1 = 12; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_four_four_TypeI_SinglePanel_Restriction): - *n1 = 4; - *n2 = 4; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_eight_two_TypeI_SinglePanel_Restriction): - *n1 = 8; - *n2 = 2; - *o1 = 4; - *o2 = 4; - break; - case (NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_sixteen_one_TypeI_SinglePanel_Restriction): - *n1 = 16; - *n2 = 1; - *o1 = 4; - *o2 = 1; - break; - default: - AssertFatal(1==0,"Not supported configuration for n1_n2 in codebook configuration"); - } -} - -void get_x1x2_bitlen_singlepanel(int n1, int n2, int o1, int o2, - int *x1, int *x2, int rank, int codebook_mode) { - - // Table 6.3.1.1.2-1 in 38.212 - switch(rank){ - case 1: - if(n2>1) { - if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 2; - } - else { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2)); - *x2 = 4; - } - } - else{ - if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 2; - } - else { - *x1 = ceil(log2(n1*o1/2)); - *x2 = 4; - } - } - break; - case 2: - if(n1*n2 == 2) { - if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; - } - else { - *x1 = ceil(log2(n1*o1/2)); - *x2 = 3; - } - *x1 += 1; - } - else { - if(n2>1) { - if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 3; - } - else { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2/2)); - *x2 = 3; - } - } - else{ - if (codebook_mode == 1) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; - } - else { - *x1 = ceil(log2(n1*o1/2)); - *x2 = 3; - } - } - *x1 += 2; - } - break; - case 3: - case 4: - if(n1*n2 == 2) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; - } - else { - if(n1*n2 >= 8) { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)) + 2; - *x2 = 1; - } - else { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)) + 2; - *x2 = 1; - } - } - break; - case 5: - case 6: - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; - break; - case 7: - case 8: - if(n1 == 4 && n2 == 1) { - *x1 = ceil(log2(n1*o1/2)) + ceil(log2(n2*o2)); - *x2 = 1; - } - else { - if(n1 > 2 && n2 == 2) { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2/2)); - *x2 = 1; - } - else { - *x1 = ceil(log2(n1*o1)) + ceil(log2(n2*o2)); - *x2 = 1; - } - } - break; - default: - AssertFatal(1==0,"Invalid rank in x1 x2 bit length computation\n"); - } -} - - -void compute_pmi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, - uint8_t ri_restriction, - nr_csi_report_t *csi_report){ - - struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; - for(int i=0; i<8; i++) { - csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=0; - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=0; - if (codebookConfig == NULL || ((ri_restriction>>i)&0x01) == 0) - return; - else { - if(codebookConfig->codebookType.present == NR_CodebookConfig__codebookType_PR_type1) { - if(codebookConfig->codebookType.choice.type1->subType.present == NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel) { - if(codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.present == - NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_two) { - csi_report->N1 = 1; - csi_report->N2 = 1; - if (i==0) - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=2; - if (i==1) - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=1; - } - else { // more than two - int n1,n2,o1,o2,x1,x2; - get_n1n2_o1o2_singlepanel(&n1,&n2,&o1,&o2,codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel->nrOfAntennaPorts.choice.moreThanTwo); - get_x1x2_bitlen_singlepanel(n1,n2,o1,o2,&x1,&x2,i+1,codebookConfig->codebookType.choice.type1->codebookMode); - csi_report->N1 = n1; - csi_report->N2 = n2; - csi_report->codebook_mode = codebookConfig->codebookType.choice.type1->codebookMode; - csi_report->csi_meas_bitlen.pmi_x1_bitlen[i]=x1; - csi_report->csi_meas_bitlen.pmi_x2_bitlen[i]=x2; - } - } - else - AssertFatal(1==0,"Type1 Multi-panel Codebook Config not yet implemented\n"); - } - else - AssertFatal(1==0,"Type2 Codebook Config not yet implemented\n"); - } - } -} - -void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig, - uint8_t ri_restriction, - nr_csi_report_t *csi_report){ - - struct NR_CodebookConfig *codebookConfig = csi_reportconfig->codebookConfig; - struct NR_CSI_ReportConfig__reportFreqConfiguration *freq_config = csi_reportconfig->reportFreqConfiguration; - - if (*freq_config->cqi_FormatIndicator == NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI) { - for(int i=0; i<8; i++) { - if ((ri_restriction>>i)&0x01) { - csi_report->csi_meas_bitlen.cqi_bitlen[i] = 4; - if(codebookConfig != NULL) { - if (NR_CodebookConfig__codebookType__type1__subType_PR_typeI_SinglePanel == codebookConfig->codebookType.choice.type1->subType.present){ - struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel *type1single = codebookConfig->codebookType.choice.type1->subType.choice.typeI_SinglePanel; - if (type1single->nrOfAntennaPorts.present == NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts_PR_moreThanTwo) { - if (type1single->nrOfAntennaPorts.choice.moreThanTwo->n1_n2.present > - NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo__n1_n2_PR_two_one_TypeI_SinglePanel_Restriction) { - // more than 4 antenna ports - if (i > 4) - csi_report->csi_meas_bitlen.cqi_bitlen[i] += 4; // CQI for second TB - } - } - } - } - } - else - csi_report->csi_meas_bitlen.cqi_bitlen[i] = 0; - } - } - else - AssertFatal(1==0,"Sub-band CQI reporting not yet supported"); -} - -//!TODO : same function can be written to handle csi_resources -void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE){ - uint8_t csi_report_id = 0; - uint8_t nb_resources = 0; - NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; - NR_CSI_ResourceConfigId_t csi_ResourceConfigId; - struct NR_CSI_ResourceConfig *csi_resourceconfig; - - // for each CSI measurement report configuration (list of CSI-ReportConfig) - LOG_D(NR_MAC,"Searching %d csi_reports\n",csi_MeasConfig->csi_ReportConfigToAddModList->list.count); - for (csi_report_id=0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ - struct NR_CSI_ReportConfig *csi_reportconfig = csi_MeasConfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; - // MAC structure for CSI measurement reports (per UE and per report) - nr_csi_report_t *csi_report = &UE->csi_report_template[csi_report_id]; - // csi-ResourceConfigId of a CSI-ResourceConfig included in the configuration - // (either CSI-RS or SSB) - csi_ResourceConfigId = csi_reportconfig->resourcesForChannelMeasurement; - // looking for CSI-ResourceConfig - int found_resource = 0; - int csi_resourceidx = 0; - while (found_resource == 0 && csi_resourceidx < csi_MeasConfig->csi_ResourceConfigToAddModList->list.count) { - csi_resourceconfig = csi_MeasConfig->csi_ResourceConfigToAddModList->list.array[csi_resourceidx]; - if ( csi_resourceconfig->csi_ResourceConfigId == csi_ResourceConfigId) - found_resource = 1; - csi_resourceidx++; - } - AssertFatal(found_resource==1,"Not able to found any CSI-ResourceConfig with csi-ResourceConfigId %ld\n", - csi_ResourceConfigId); - - long resourceType = csi_resourceconfig->resourceType; - - reportQuantity_type = csi_reportconfig->reportQuantity.present; - csi_report->reportQuantity_type = reportQuantity_type; - - // setting the CSI or SSB index list - if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP == csi_report->reportQuantity_type) { - for (int csi_idx = 0; csi_idx < csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.count; csi_idx++) { - if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceSetId == - *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list.array[0])){ - //We can configure only one SSB resource set from spec 38.331 IE CSI-ResourceConfig - nb_resources= csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.count; - csi_report->SSB_Index_list = csi_MeasConfig->csi_SSB_ResourceSetToAddModList->list.array[csi_idx]->csi_SSB_ResourceList.list.array; - csi_report->CSI_Index_list = NULL; - break; - } - } - } - else { - if (resourceType == NR_CSI_ResourceConfig__resourceType_periodic) { - AssertFatal(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList != NULL, - "Wrong settings! Report quantity requires CSI-RS but csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList is NULL\n"); - for (int csi_idx = 0; csi_idx < csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.count; csi_idx++) { - if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_ResourceSetId == - *(csi_resourceconfig->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->nzp_CSI_RS_ResourceSetList->list.array[0])) { - //For periodic and semi-persistent CSI Resource Settings, the number of CSI-RS Resource Sets configured is limited to S=1 for spec 38.212 - nb_resources = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.count; - csi_report->CSI_Index_list = csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList->list.array[csi_idx]->nzp_CSI_RS_Resources.list.array; - csi_report->SSB_Index_list = NULL; - break; - } - } - } - else AssertFatal(1==0,"Only periodic resource configuration currently supported\n"); - } - LOG_D(NR_MAC,"nb_resources %d\n",nb_resources); - // computation of bit length depending on the report type - switch(reportQuantity_type){ - case (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP): - compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report); - break; - case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP): - compute_rsrp_bitlen(csi_reportconfig, nb_resources, csi_report); - break; - case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI): - csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); - csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); - compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - break; - case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI): - csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); - csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); - compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - break; - case (NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI): - csi_report->csi_meas_bitlen.cri_bitlen=ceil(log2(nb_resources)); - csi_report->csi_meas_bitlen.ri_restriction = compute_ri_bitlen(csi_reportconfig, csi_report); - compute_li_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - compute_cqi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - compute_pmi_bitlen(csi_reportconfig, csi_report->csi_meas_bitlen.ri_restriction, csi_report); - break; - default: - AssertFatal(1==0,"Not yet supported CSI report quantity type"); - } - } -} - - -uint16_t nr_get_csi_bitlen(NR_UE_info_t *UE, - uint8_t csi_report_id) { - - uint16_t csi_bitlen = 0; - uint16_t max_bitlen = 0; - L1_RSRP_bitlen_t * CSI_report_bitlen = NULL; - CSI_Meas_bitlen_t * csi_meas_bitlen = NULL; - - if (NR_CSI_ReportConfig__reportQuantity_PR_ssb_Index_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type|| - NR_CSI_ReportConfig__reportQuantity_PR_cri_RSRP==UE->csi_report_template[csi_report_id].reportQuantity_type){ - CSI_report_bitlen = &(UE->csi_report_template[csi_report_id].CSI_report_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements - csi_bitlen+= ((CSI_report_bitlen->cri_ssbri_bitlen * CSI_report_bitlen->nb_ssbri_cri) + - CSI_report_bitlen->rsrp_bitlen +(CSI_report_bitlen->diff_rsrp_bitlen * - (CSI_report_bitlen->nb_ssbri_cri -1 ))); - } else{ - csi_meas_bitlen = &(UE->csi_report_template[csi_report_id].csi_meas_bitlen); //This might need to be moodif for Aperiodic CSI-RS measurements - uint16_t temp_bitlen; - for (int i=0; i<8; i++) { - temp_bitlen = (csi_meas_bitlen->cri_bitlen+ - csi_meas_bitlen->ri_bitlen+ - csi_meas_bitlen->li_bitlen[i]+ - csi_meas_bitlen->cqi_bitlen[i]+ - csi_meas_bitlen->pmi_x1_bitlen[i]+ - csi_meas_bitlen->pmi_x2_bitlen[i]); - if(temp_bitlen>max_bitlen) - max_bitlen = temp_bitlen; - } - csi_bitlen += max_bitlen; - } - - return csi_bitlen; -} - - void nr_csi_meas_reporting(int Mod_idP, frame_t frame, sub_frame_t slot) { - NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels->ServingCellConfigCommon; - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; - - UE_iterator(RC.nrmac[Mod_idP]->UE_info.list, UE ) { - const NR_CellGroupConfig_t *CellGroup = UE->CellGroup; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; if ((sched_ctrl->rrc_processing_timer > 0) || (sched_ctrl->ul_failure==1 && get_softmodem_params()->phy_test==0)) { continue; } - if (!CellGroup || !CellGroup->spCellConfig || !CellGroup->spCellConfig->spCellConfigDedicated || - !CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig) continue; - const NR_CSI_MeasConfig_t *csi_measconfig = CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + const NR_CSI_MeasConfig_t *csi_measconfig = ul_bwp->csi_MeasConfig; + if (!csi_measconfig) continue; AssertFatal(csi_measconfig->csi_ReportConfigToAddModList->list.count > 0, "NO CSI report configuration available"); - NR_PUCCH_Config_t *pucch_Config = NULL; - if (sched_ctrl->active_ubwp) { - pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; - } else if (CellGroup && - CellGroup->spCellConfig && - CellGroup->spCellConfig->spCellConfigDedicated && - CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig && - CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && - CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { - pucch_Config = CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; - } + NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; for (int csi_report_id = 0; csi_report_id < csi_measconfig->csi_ReportConfigToAddModList->list.count; csi_report_id++){ NR_CSI_ReportConfig_t *csirep = csi_measconfig->csi_ReportConfigToAddModList->list.array[csi_report_id]; @@ -760,14 +212,9 @@ void nr_csi_meas_reporting(int Mod_idP, curr_pucch->frame = frame; curr_pucch->ul_slot = sched_slot; curr_pucch->resource_indicator = res_index; - curr_pucch->csi_bits += nr_get_csi_bitlen(UE,csi_report_id); - - const NR_SIB1_t *sib1 = RC.nrmac[Mod_idP]->common_channels[0].sib1 ? RC.nrmac[Mod_idP]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL; - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - scc, - sib1); + curr_pucch->csi_bits += nr_get_csi_bitlen(UE->csi_report_template, csi_report_id); - int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); + int bwp_start = ul_bwp->BWPStart; // going through the list of PUCCH resources to find the one indexed by resource_id uint16_t *vrb_map_UL = &RC.nrmac[Mod_idP]->common_channels[0].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; @@ -824,16 +271,9 @@ static void handle_dl_harq(NR_UE_info_t * UE, add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid); harq->round = 0; harq->ndi ^= 1; - } else if (harq->round >= harq_round_max - 1) { - add_tail_nr_list(&UE->UE_sched_ctrl.available_dl_harq, harq_pid); - harq->round = 0; - harq->ndi ^= 1; - - NR_mac_stats_t *stats = &UE->mac_stats; - stats->dl.errors++; - LOG_D(NR_MAC, "retransmission error for UE %04x (total %"PRIu64")\n", UE->rnti, stats->dl.errors); - + abort_nr_dl_harq(UE, harq_pid); + LOG_D(NR_MAC, "retransmission error for UE %04x (total %"PRIu64")\n", UE->rnti, UE->mac_stats.dl.errors); } else { LOG_D(PHY,"NACK for: pid %d, ue %04x\n",harq_pid, UE->rnti); add_tail_nr_list(&UE->UE_sched_ctrl.retrans_dl_harq, harq_pid); @@ -842,13 +282,13 @@ static void handle_dl_harq(NR_UE_info_t * UE, } int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t * UE) { - NR_CellGroupConfig_t *CellGroup = UE->CellGroup; - int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count; + + const NR_PDSCH_Config_t *pdsch_Config = UE->current_DL_BWP.pdsch_Config; + int nb_tci_states = pdsch_Config ? pdsch_Config->tci_StatesToAddModList->list.count : 0; NR_TCI_State_t *tci =NULL; - int i; - for(i=0; i<nb_tci_states && i<64; i++) { - tci = (NR_TCI_State_t *)CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i]; + for(int i=0; i<nb_tci_states && i<64; i++) { + tci = (NR_TCI_State_t *)pdsch_Config->tci_StatesToAddModList->list.array[i]; if(tci != NULL) { if(tci->qcl_Type1.referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) { @@ -868,18 +308,17 @@ int checkTargetSSBInFirst64TCIStates_pdschConfig(int ssb_index_t, NR_UE_info_t * } int checkTargetSSBInTCIStates_pdcchConfig(int ssb_index_t, NR_UE_info_t *UE) { - NR_CellGroupConfig_t *CellGroup = UE->CellGroup ; - int nb_tci_states = CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.count; + NR_TCI_State_t *tci =NULL; NR_TCI_StateId_t *tci_id = NULL; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; - int i; int flag = 0; int tci_stateID = -1; - - for(i=0; i<nb_tci_states && i<128; i++) { - tci = (NR_TCI_State_t *)CellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->tci_StatesToAddModList->list.array[i]; + const NR_PDSCH_Config_t *pdsch_Config = UE->current_DL_BWP.pdsch_Config; + int nb_tci_states = pdsch_Config ? pdsch_Config->tci_StatesToAddModList->list.count : 0; + for(int i=0; i<nb_tci_states && i<128; i++) { + tci = (NR_TCI_State_t *)pdsch_Config->tci_StatesToAddModList->list.array[i]; if(tci != NULL && tci->qcl_Type1.referenceSignal.present == NR_QCL_Info__referenceSignal_PR_ssb) { if(tci->qcl_Type1.referenceSignal.choice.ssb == ssb_index_t) { @@ -935,21 +374,12 @@ void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) { uint8_t target_ssb_beam_index = curr_ssb_beam_index; uint8_t is_triggering_ssb_beam_switch =0; uint8_t ssb_idx = 0; - int pdsch_bwp_id =0; + int pdsch_bwp_id = 0; int ssb_index[MAX_NUM_SSB] = {0}; int ssb_rsrp[MAX_NUM_SSB] = {0}; uint8_t idx = 0; - + NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0; - NR_CellGroupConfig_t *CellGroup = UE->CellGroup; - - //bwp indicator - int n_dl_bwp=0; - if (CellGroup->spCellConfig && - CellGroup->spCellConfig->spCellConfigDedicated && - CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList) - n_dl_bwp = CellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; uint8_t nr_ssbri_cri = 0; uint8_t nb_of_csi_ssb_report = UE->csi_report_template[cqi_idx].nb_of_csi_ssb_report; @@ -957,6 +387,9 @@ void tci_handling(NR_UE_info_t *UE, frame_t frame, slot_t slot) { uint8_t diff_rsrp_idx = 0; uint8_t i, j; + //bwp indicator + int n_dl_bwp = dl_bwp->n_dl_bwp; + const int bwp_id = dl_bwp->bwp_id; if (n_dl_bwp < 4) pdsch_bwp_id = bwp_id; else @@ -1183,7 +616,6 @@ void evaluate_rsrp_report(NR_UE_info_t *UE, stats->num_rsrp_meas++; } - void evaluate_cri_report(uint8_t *payload, uint8_t cri_bitlen, int cumul_bits, @@ -1219,9 +651,11 @@ void evaluate_cqi_report(uint8_t *payload, nr_csi_report_t *csi_report, int cumul_bits, uint8_t ri, - NR_UE_sched_ctrl_t *sched_ctrl, + NR_UE_info_t *UE, long *cqi_Table){ + NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + //TODO sub-band CQI report not yet implemented int cqi_bitlen = csi_report->csi_meas_bitlen.cqi_bitlen[ri]; @@ -1244,7 +678,7 @@ void evaluate_cqi_report(uint8_t *payload, // TODO for wideband case and multiple TB const int cqi_idx = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb; - const int mcs_table = sched_ctrl->pdsch_semi_static.mcsTableIdx; + const int mcs_table = UE->current_DL_BWP.mcsTableIdx; const int cqi_table = sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.cqi_table; sched_ctrl->dl_max_mcs = get_mcs_from_cqi(mcs_table, cqi_table, cqi_idx); } @@ -1319,11 +753,12 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_ServingCellConfigCommon_t *scc) { /** From Table 6.3.1.1.2-3: RI, LI, CQI, and CRI of codebookType=typeI-SinglePanel */ - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; uint8_t *payload = uci_pdu->csi_part1.csi_part1_payload; uint16_t bitlen = uci_pdu->csi_part1.csi_part1_bit_len; NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type = NR_CSI_ReportConfig__reportQuantity_PR_NOTHING; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; int cumul_bits = 0; int r_index = -1; for (int csi_report_id = 0; csi_report_id < csi_MeasConfig->csi_ReportConfigToAddModList->list.count; csi_report_id++ ) { @@ -1358,7 +793,7 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, cumul_bits += ri_bitlen; if (r_index != -1) skip_zero_padding(&cumul_bits,csi_report,r_index,bitlen); - evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl,csirep->cqi_Table); + evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,csirep->cqi_Table); break; case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_PMI_CQI: cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen; @@ -1374,7 +809,7 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, pmi_bitlen = evaluate_pmi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl); sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id = csi_report_id; cumul_bits += pmi_bitlen; - evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl,csirep->cqi_Table); + evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,csirep->cqi_Table); break; case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI: cri_bitlen = csi_report->csi_meas_bitlen.cri_bitlen; @@ -1392,7 +827,7 @@ void extract_pucch_csi_report(NR_CSI_MeasConfig_t *csi_MeasConfig, pmi_bitlen = evaluate_pmi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl); sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.csi_report_id = csi_report_id; cumul_bits += pmi_bitlen; - evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,sched_ctrl,csirep->cqi_Table); + evaluate_cqi_report(payload,csi_report,cumul_bits,r_index,UE,csirep->cqi_Table); break; default: AssertFatal(1==0, "Invalid or not supported CSI measurement report\n"); @@ -1462,7 +897,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, for (int harq_bit = 0; harq_bit < uci_01->harq->num_harq; harq_bit++) { const uint8_t harq_value = uci_01->harq->harq_list[harq_bit].harq_value; const uint8_t harq_confidence = uci_01->harq->harq_confidence_level; - NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max); + NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max); if (!harq) { LOG_E(NR_MAC, "Oh no! Could not find a harq in %s!\n", __FUNCTION__); break; @@ -1471,7 +906,7 @@ void handle_nr_uci_pucch_0_1(module_id_t mod_id, const int8_t pid = sched_ctrl->feedback_dl_harq.head; remove_front_nr_list(&sched_ctrl->feedback_dl_harq); LOG_D(NR_MAC,"%4d.%2d bit %d pid %d ack/nack %d\n",frame, slot, harq_bit,pid,harq_value); - handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->harq_round_max); + handle_dl_harq(UE, pid, harq_value == 0 && harq_confidence == 0, RC.nrmac[mod_id]->dl_bler.harq_round_max); if (harq_confidence == 1) UE->mac_stats.pucch0_DTX++; } } @@ -1502,15 +937,10 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, LOG_E(NR_MAC, "%s(): unknown RNTI %04x in PUCCH UCI\n", __func__, uci_234->rnti); return; } - AssertFatal(UE->CellGroup,"Cellgroup is null for UE %04x\n", uci_234->rnti); - AssertFatal(UE->CellGroup->spCellConfig, - "Cellgroup->spCellConfig is null for UE %04x\n", uci_234->rnti); - AssertFatal(UE->CellGroup->spCellConfig->spCellConfigDedicated, - "Cellgroup->spCellConfig->spCellConfigDedicated is null for UE %04x\n", uci_234->rnti); - if ( UE->CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig==NULL) - return; - NR_CSI_MeasConfig_t *csi_MeasConfig = UE->CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup; + NR_CSI_MeasConfig_t *csi_MeasConfig = UE->current_UL_BWP.csi_MeasConfig; + if (csi_MeasConfig==NULL) + return; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; // tpc (power control) @@ -1524,13 +954,13 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, // iterate over received harq bits for (int harq_bit = 0; harq_bit < uci_234->harq.harq_bit_len; harq_bit++) { const int acknack = ((uci_234->harq.harq_payload[harq_bit >> 3]) >> harq_bit) & 0x01; - NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->harq_round_max); + NR_UE_harq_t *harq = find_harq(frame, slot, UE, RC.nrmac[mod_id]->dl_bler.harq_round_max); if (!harq) break; DevAssert(harq->is_waiting); const int8_t pid = sched_ctrl->feedback_dl_harq.head; remove_front_nr_list(&sched_ctrl->feedback_dl_harq); - handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->harq_round_max); + handle_dl_harq(UE, pid, uci_234->harq.harq_crc != 1 && acknack, RC.nrmac[mod_id]->dl_bler.harq_round_max); } } if ((uci_234->pduBitmap >> 2) & 0x01) { @@ -1599,7 +1029,6 @@ bool test_acknack_vrb_occupation(NR_UE_sched_ctrl_t *sched_ctrl, return true; } - // this function returns an index to NR_sched_pucch structure // currently this structure contains PUCCH0 at index 0 and PUCCH2 at index 1 // if the function returns -1 it was not possible to schedule acknack @@ -1613,7 +1042,8 @@ int nr_acknack_scheduling(int mod_id, const int CC_id = 0; const int minfbtime = RC.nrmac[mod_id]->minRXTXTIMEpdsch; const NR_ServingCellConfigCommon_t *scc = RC.nrmac[mod_id]->common_channels[CC_id].ServingCellConfigCommon; - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + const NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; AssertFatal(tdd || RC.nrmac[mod_id]->common_channels[CC_id].frame_type == FDD, "Dynamic TDD not handled yet\n"); const int nr_slots_period = tdd ? n_slots_frame / get_nb_periods_per_frame(tdd->dl_UL_TransmissionPeriodicity) : n_slots_frame; @@ -1628,23 +1058,10 @@ int nr_acknack_scheduling(int mod_id, * later) * * each UE has dedicated PUCCH Format 0 resources, and we use index 0! */ NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - NR_CellGroupConfig_t *cg = UE->CellGroup; - - NR_PUCCH_Config_t *pucch_Config = NULL; - if (sched_ctrl->active_ubwp) { - pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; - } else if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { - pucch_Config = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; - } - NR_BWP_t *genericParameters = sched_ctrl->active_ubwp ? - &sched_ctrl->active_ubwp->bwp_Common->genericParameters: - &scc->uplinkConfigCommon->initialUplinkBWP->genericParameters; - int bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - int bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; + + int bwp_start = ul_bwp->BWPStart; + int bwp_size = ul_bwp->BWPSize; NR_sched_pucch_t *pucch = &sched_ctrl->sched_pucch[0]; LOG_D(NR_MAC, "In %s: %4d.%2d Trying to allocate pucch, current DAI %d\n", __FUNCTION__, frame, slot, pucch->dai_c); @@ -1668,7 +1085,7 @@ int nr_acknack_scheduling(int mod_id, && csi_pucch->csi_bits > 0 && csi_pucch->frame == f && csi_pucch->ul_slot == s)) - nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE); + nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE); memset(pucch, 0, sizeof(*pucch)); pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; @@ -1699,22 +1116,13 @@ int nr_acknack_scheduling(int mod_id, LOG_D(NR_MAC, "In %s: pucch_acknak 1. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame, slot, pucch->frame, pucch->ul_slot, pucch->dai_c); - // this is hardcoded for now as ue specific only if we are not on the initialBWP (to be fixed to allow ue_Specific also on initialBWP - NR_BWP_UplinkDedicated_t *ubwpd=NULL; - - if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) - ubwpd = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP; + nr_dci_format_t dci_format = NR_DL_DCI_FORMAT_1_0; + if(is_common == 0) + dci_format = UE->current_DL_BWP.dci_format; - NR_SearchSpace__searchSpaceType_PR ss_type = (is_common==0 && (sched_ctrl->active_bwp || ubwpd)) ? NR_SearchSpace__searchSpaceType_PR_ue_Specific: NR_SearchSpace__searchSpaceType_PR_common; uint8_t pdsch_to_harq_feedback[8]; - const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0; - int max_fb_time = 0; - get_pdsch_to_harq_feedback(UE, bwp_id, ss_type, &max_fb_time, pdsch_to_harq_feedback); + get_pdsch_to_harq_feedback(pucch_Config, dci_format, &max_fb_time, pdsch_to_harq_feedback); LOG_D(NR_MAC, "In %s: 1b. DL %4d.%2d, UL_ACK %4d.%2d, DAI_C %d\n", __FUNCTION__, frame,slot,pucch->frame,pucch->ul_slot,pucch->dai_c); /* there is a HARQ. Check whether we can use it for this ACKNACK */ @@ -1735,13 +1143,12 @@ int nr_acknack_scheduling(int mod_id, // we cannot reach this timing anymore, allocate and try again const int f = pucch->frame; const int s = pucch->ul_slot; - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; LOG_D(NR_MAC, "In %s: %4d.%2d DAI > 0, cannot reach timing for pucch in %4d.%2d, advancing slot by 1 and trying again\n", __FUNCTION__, frame, slot, f, s); if (!(csi_pucch && csi_pucch->csi_bits > 0 && csi_pucch->frame == f && csi_pucch->ul_slot == s)) - nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE); + nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE); memset(pucch, 0, sizeof(*pucch)); pucch->frame = s == n_slots_frame - 1 ? (f + 1) % 1024 : f; if(((s + 1)%nr_slots_period) == 0) @@ -1840,10 +1247,10 @@ int nr_acknack_scheduling(int mod_id, csi_pucch->ul_slot == pucch->ul_slot) { // skip the CSI PUCCH if it is present and if in the next frame/slot // and if we don't multiplex - // FIXME currently we support at most 11 bits in pucch2 so skip also in that case + /* FIXME currently we support at most 11 bits in pucch2 so skip also in that case. + We need to set the limit to 10 because SR scheduling has been moved afterwards */ if(!csi_pucch->simultaneous_harqcsi - || ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 11)) { - + || ((csi_pucch->csi_bits + csi_pucch->dai_c) >= 10)) { LOG_D(NR_MAC,"Cannot multiplex csi_pucch %d +csi_pucch->dai_c %d for %d.%d\n",csi_pucch->csi_bits,csi_pucch->dai_c,csi_pucch->frame,csi_pucch->ul_slot); nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, csi_pucch, UE); memset(csi_pucch, 0, sizeof(*csi_pucch)); @@ -1863,9 +1270,7 @@ int nr_acknack_scheduling(int mod_id, else { csi_pucch->timing_indicator = ind_found; csi_pucch->dai_c++; - // keep updating format 2 indicator - pucch->timing_indicator = ind_found; // index in the list of timing indicators - pucch->dai_c++; + memset(pucch,0,sizeof(*pucch)); LOG_D(NR_MAC,"multiplexing csi_pucch %d +csi_pucch->dai_c %d for %d.%d\n",csi_pucch->csi_bits,csi_pucch->dai_c,csi_pucch->frame,csi_pucch->ul_slot); return 1; @@ -1898,31 +1303,20 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot) { if (!is_xlsch_in_slot(nrmac->ulsch_slot_bitmap[slot / 64], slot)) return; - NR_ServingCellConfigCommon_t *scc = nrmac->common_channels->ServingCellConfigCommon; - const int n_slots_frame = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; + UE_iterator(nrmac->UE_info.list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; + NR_UE_UL_BWP_t *ul_bwp = &UE->current_UL_BWP; + const int n_slots_frame = nr_slots_per_frame[ul_bwp->scs]; + if (sched_ctrl->ul_failure==1 || sched_ctrl->rrc_processing_timer>0) continue; + NR_PUCCH_Config_t *pucch_Config = ul_bwp->pucch_Config; - if (sched_ctrl->ul_failure==1) continue; - NR_PUCCH_Config_t *pucch_Config = NULL; - if (sched_ctrl->active_ubwp) { - pucch_Config = sched_ctrl->active_ubwp->bwp_Dedicated->pucch_Config->choice.setup; - } else if (UE->CellGroup && - UE->CellGroup->spCellConfig && - UE->CellGroup->spCellConfig->spCellConfigDedicated && - UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig && - UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP && - UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup) { - pucch_Config = UE->CellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->pucch_Config->choice.setup; - } - - else continue; - if (!pucch_Config->schedulingRequestResourceToAddModList) - continue; + if (!pucch_Config || !pucch_Config->schedulingRequestResourceToAddModList) + continue; AssertFatal(pucch_Config->schedulingRequestResourceToAddModList->list.count>0,"NO SR configuration available"); - for (int SR_resource_id =0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) { + for (int SR_resource_id = 0; SR_resource_id < pucch_Config->schedulingRequestResourceToAddModList->list.count;SR_resource_id++) { NR_SchedulingRequestResourceConfig_t *SchedulingRequestResourceConfig = pucch_Config->schedulingRequestResourceToAddModList->list.array[SR_resource_id]; int SR_period; int SR_offset; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index fe921a6d2a1eababac374d114d082af1bd6e79e9..43e88eb9a943ae22f21c56cb29e52680f4c2ccf1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -37,14 +37,7 @@ #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" -int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl) { - - int dci_format = sched_ctrl->search_space && sched_ctrl->search_space->searchSpaceType && - sched_ctrl->search_space->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific ? - NR_UL_DCI_FORMAT_0_1 : NR_UL_DCI_FORMAT_0_0; - - return(dci_format); -} +//#define SRS_IND_DEBUG const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot) { @@ -319,52 +312,51 @@ int nr_process_mac_pdu( instance_t module_idP, mac_len = 6; } - nr_mac_rrc_data_ind(module_idP, - CC_id, - frameP, - 0, - 0, - UE->rnti, - CCCH, - pduP + mac_subheader_len, - mac_len, - 0); + send_initial_ul_rrc_message(module_idP, + CC_id, + UE, + CCCH, + pduP + mac_subheader_len, + mac_len); break; case UL_SCH_LCID_DTCH ... (UL_SCH_LCID_DTCH + 28): // check if LCID is valid at current time. - if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) - return 0; + if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len)) { + return 0; + } - LOG_D(NR_MAC, "[UE %04x] %d.%d : ULSCH -> UL-%s %d (gNB %ld, %d bytes)\n", - UE->rnti, - frameP, - slot, - rx_lcid<4?"DCCH":"DTCH", - rx_lcid, - module_idP, - mac_len); - UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len; - - mac_rlc_data_ind(module_idP, - UE->rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - rx_lcid, - (char *)(pduP + mac_subheader_len), - mac_len, - 1, - NULL); - - /* Updated estimated buffer when receiving data */ - if (sched_ctrl->estimated_ul_buffer >= mac_len) - sched_ctrl->estimated_ul_buffer -= mac_len; - else - sched_ctrl->estimated_ul_buffer = 0; - break; + LOG_D(NR_MAC, "[UE %04x] %d.%d : ULSCH -> UL-%s %d (gNB %ld, %d bytes)\n", + UE->rnti, + frameP, + slot, + rx_lcid<4?"DCCH":"DTCH", + rx_lcid, + module_idP, + mac_len); + UE->mac_stats.ul.lc_bytes[rx_lcid] += mac_len; + + mac_rlc_data_ind(module_idP, + UE->rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + rx_lcid, + (char *)(pduP + mac_subheader_len), + mac_len, + 1, + NULL); + + /* Updated estimated buffer when receiving data */ + if (sched_ctrl->estimated_ul_buffer >= mac_len) { + sched_ctrl->estimated_ul_buffer -= mac_len; + } else { + sched_ctrl->estimated_ul_buffer = 0; + } + + break; default: LOG_E(NR_MAC, "Received unknown MAC header (LCID = 0x%02x)\n", rx_lcid); @@ -399,7 +391,7 @@ int nr_process_mac_pdu( instance_t module_idP, return 0; } -void abort_nr_ul_harq( NR_UE_info_t* UE, int8_t harq_pid) +void abort_nr_ul_harq(NR_UE_info_t *UE, int8_t harq_pid) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_UE_ul_harq_t *harq = &sched_ctrl->ul_harq_processes[harq_pid]; @@ -449,7 +441,7 @@ void handle_nr_ul_harq(const int CC_idP, remove_front_nr_list(&sched_ctrl->feedback_ul_harq); sched_ctrl->ul_harq_processes[harq_pid].is_waiting = false; - if(sched_ctrl->ul_harq_processes[harq_pid].round >= RC.nrmac[mod_id]->harq_round_max - 1) { + if(sched_ctrl->ul_harq_processes[harq_pid].round >= RC.nrmac[mod_id]->ul_bler.harq_round_max - 1) { abort_nr_ul_harq(UE, harq_pid); } else { sched_ctrl->ul_harq_processes[harq_pid].round++; @@ -470,7 +462,7 @@ void handle_nr_ul_harq(const int CC_idP, harq_pid, crc_pdu->rnti); add_tail_nr_list(&sched_ctrl->available_ul_harq, harq_pid); - } else if (harq->round >= RC.nrmac[mod_id]->harq_round_max - 1) { + } else if (harq->round >= RC.nrmac[mod_id]->ul_bler.harq_round_max - 1) { abort_nr_ul_harq(UE, harq_pid); LOG_D(NR_MAC, "RNTI %04x: Ulharq id %d crc failed in all rounds\n", @@ -543,7 +535,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, else{ LOG_D(NR_MAC,"[UE %04x] Detected DTX : increasing UE TX power\n",UE->rnti); UE_scheduling_control->tpc0 = 1; - } #if defined(ENABLE_MAC_PAYLOAD_DEBUG) @@ -746,14 +737,13 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, return; } - if (ra->msg3_round >= MAX_HARQ_ROUNDS - 1) { - LOG_D(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state); + if (ra->msg3_round >= gNB_mac->ul_bler.harq_round_max - 1) { + LOG_W(NR_MAC, "Random Access %i failed at state %i (Reached msg3 max harq rounds)\n", i, ra->state); nr_mac_remove_ra_rnti(gnb_mod_idP, ra->rnti); nr_clear_ra_proc(gnb_mod_idP, CC_idP, frameP, ra); return; } - LOG_D(NR_MAC, "Random Access %i Msg3 CRC did not pass)\n", i); ra->msg3_round++; @@ -762,23 +752,64 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } } -long get_K2(NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfigCommonSIB_t *scc_sib1, - NR_BWP_Uplink_t *ubwp, +void handle_nr_srs_measurements(const module_id_t module_id, + const frame_t frame, + const sub_frame_t slot, + const rnti_t rnti, + const uint16_t timing_advance, + const uint8_t num_symbols, + const uint8_t wide_band_snr, + const uint8_t num_reported_symbols, + nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list) { + + LOG_D(NR_MAC, "(%d.%d) Received SRS indication for rnti: 0x%04x\n", frame, slot, rnti); + +#ifdef SRS_IND_DEBUG + LOG_I(NR_MAC, "frame = %i\n", frame); + LOG_I(NR_MAC, "slot = %i\n", slot); + LOG_I(NR_MAC, "rnti = 0x%04x\n", rnti); + LOG_I(NR_MAC, "timing_advance = %i\n", timing_advance); + LOG_I(NR_MAC, "num_symbols = %i\n", num_symbols); + LOG_I(NR_MAC, "wide_band_snr = %i (%i dB)\n", wide_band_snr, (wide_band_snr>>1)-64); + LOG_I(NR_MAC, "num_reported_symbols = %i\n", num_reported_symbols); + LOG_I(NR_MAC, "reported_symbol_list[0].num_rbs = %i\n", reported_symbol_list[0].num_rbs); + for(int rb = 0; rb < reported_symbol_list[0].num_rbs; rb++) { + LOG_I(NR_MAC, "reported_symbol_list[0].rb_list[%3i].rb_snr = %i (%i dB)\n", + rb, reported_symbol_list[0].rb_list[rb].rb_snr, (reported_symbol_list[0].rb_list[rb].rb_snr>>1)-64); + } +#endif + + NR_UE_info_t *UE = find_nr_UE(&RC.nrmac[module_id]->UE_info, rnti); + if (!UE) { + LOG_W(NR_MAC, "Could not find UE for RNTI 0x%04x\n", rnti); + return; + } + + gNB_MAC_INST *nr_mac = RC.nrmac[module_id]; + NR_mac_stats_t *stats = &UE->mac_stats; + stats->srs_wide_band_snr = (wide_band_snr>>1)-64; + + const int ul_prbblack_SNR_threshold = nr_mac->ul_prbblack_SNR_threshold; + uint16_t *ulprbbl = nr_mac->ulprbbl; + + memset(ulprbbl, 0, reported_symbol_list[0].num_rbs*sizeof(uint16_t)); + for (int rb = 0; rb < reported_symbol_list[0].num_rbs; rb++) { + int snr = (reported_symbol_list[0].rb_list[rb].rb_snr>>1)-64; + if (snr < ul_prbblack_SNR_threshold) { + ulprbbl[rb] = 0x3FFF; // all symbols taken + } + LOG_D(NR_MAC, "ulprbbl[%3i] = 0x%x\n", rb, ulprbbl[rb]); + } +} + +long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList, int time_domain_assignment, int mu) { - NR_PUSCH_TimeDomainResourceAllocation_t *tda_list = NULL; - if(ubwp) { - tda_list = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]; - } else if(scc) { - tda_list = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]; - } else if(scc_sib1) { - tda_list = scc_sib1->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[time_domain_assignment]; - } + NR_PUSCH_TimeDomainResourceAllocation_t *tda = tdaList->list.array[time_domain_assignment]; - if (tda_list->k2) - return *tda_list->k2; + if (tda->k2) + return *tda->k2; else if (mu < 2) return 1; else if (mu == 2) @@ -793,10 +824,8 @@ static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc, const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing]; const int now = frame * n + slot; - const NR_UE_sched_ctrl_t *sched_ctrl =&UE->UE_sched_ctrl; - const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; int num_slots_per_period; @@ -842,40 +871,22 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, const int CC_id = 0; NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_sched_pusch_t *retInfo = &sched_ctrl->ul_harq_processes[harq_pid].sched_pusch; - NR_CellGroupConfig_t *cg = UE->CellGroup; - - NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; - - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - (NR_ServingCellConfigCommon_t *)scc, - sib1); int rbStart = 0; // wrt BWP start - const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + const uint16_t bwpSize = UE->current_UL_BWP.BWPSize; const uint8_t nrOfLayers = 1; - const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_bwp || ubwpd) ? 1 : 2; LOG_D(NR_MAC,"retInfo->time_domain_allocation = %d, tda = %d\n", retInfo->time_domain_allocation, tda); - LOG_D(NR_MAC,"num_dmrs_cdm_grps_no_data %d, tbs %d\n",num_dmrs_cdm_grps_no_data, retInfo->tb_size); + LOG_D(NR_MAC,"tbs %d\n",retInfo->tb_size); if (tda == retInfo->time_domain_allocation) { /* check whether we need to switch the TDA allocation since tha last * (re-)transmission */ NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; - int dci_format = get_dci_format(sched_ctrl); - if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format - || ps->nrOfLayers != nrOfLayers - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) { - nr_set_pusch_semi_static(sib1, + || ps->nrOfLayers != nrOfLayers) { + nr_set_pusch_semi_static(&UE->current_UL_BWP, scc, - sched_ctrl->active_ubwp, - ubwpd, - dci_format, tda, - num_dmrs_cdm_grps_no_data, nrOfLayers, ps); } @@ -891,14 +902,9 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size); } else { NR_pusch_semi_static_t temp_ps; - int dci_format = get_dci_format(sched_ctrl); - nr_set_pusch_semi_static(sib1, + nr_set_pusch_semi_static(&UE->current_UL_BWP, scc, - sched_ctrl->active_ubwp, - ubwpd, - dci_format, tda, - num_dmrs_cdm_grps_no_data, nrOfLayers, &temp_ps); /* the retransmission will use a different time domain allocation, check @@ -993,13 +999,13 @@ static bool allocate_ul_retransmission(gNB_MAC_INST *nrmac, return true; } -void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_pusch_semi_static_t *ps) -{ +void update_ul_ue_R_Qm(NR_sched_pusch_t *sched_pusch, const NR_PUSCH_Config_t *pusch_Config, const int mcs_table) { + const int mcs = sched_pusch->mcs; - sched_pusch->R = nr_get_code_rate_ul(mcs, ps->mcs_table); - sched_pusch->Qm = nr_get_Qm_ul(mcs, ps->mcs_table); + sched_pusch->R = nr_get_code_rate_ul(mcs, mcs_table); + sched_pusch->Qm = nr_get_Qm_ul(mcs, mcs_table); - if (ps->pusch_Config && ps->pusch_Config->tp_pi2BPSK && ((ps->mcs_table == 3 && mcs < 2) || (ps->mcs_table == 4 && mcs < 6))) { + if (pusch_Config && pusch_Config->tp_pi2BPSK && ((mcs_table == 3 && mcs < 2) || (mcs_table == 4 && mcs < 6))) { sched_pusch->R >>= 1; sched_pusch->Qm <<= 1; } @@ -1018,7 +1024,7 @@ static int comparator(const void *p, const void *q) { void pf_ul(module_id_t module_id, frame_t frame, sub_frame_t slot, - NR_UE_info_t *UE_list[], + NR_UE_info_t *UE_list[], int max_num_ue, int n_rb_sched, uint16_t *rballoc_mask) { @@ -1042,18 +1048,11 @@ void pf_ul(module_id_t module_id, LOG_D(NR_MAC,"pf_ul: preparing UL scheduling for UE %04x\n",UE->rnti); NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; - - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - scc, - sib1); + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; int rbStart = 0; // wrt BWP start - NR_CellGroupConfig_t *cg = UE->CellGroup; - NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; - const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + const uint16_t bwpSize = current_BWP->BWPSize; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; const NR_mac_dir_stats_t *stats = &UE->mac_stats.ul; @@ -1079,10 +1078,11 @@ void pf_ul(module_id_t module_id, /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ remainUEs--; + // we have filled all with mandatory retransmissions + // no need to schedule new transmissions if (remainUEs == 0) - // we have filled all with mandatory retransmissions - // no need to schedule new transmissions - return; + return; + continue; } const int B = max(0, sched_ctrl->estimated_ul_buffer - sched_ctrl->sched_ul_bytes); @@ -1090,12 +1090,16 @@ void pf_ul(module_id_t module_id, const bool do_sched = nr_UE_is_to_be_scheduled(scc, 0, UE, sched_pusch->frame, sched_pusch->slot, nrmac->ulsch_max_frame_inactivity); LOG_D(NR_MAC,"pf_ul: do_sched UE %04x => %s\n",UE->rnti,do_sched ? "yes" : "no"); - if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0)) + if ((B == 0 && !do_sched) || (sched_ctrl->rrc_processing_timer > 0)) { continue; - + } + const NR_bler_options_t *bo = &nrmac->ul_bler; const int max_mcs = bo->max_mcs; /* no per-user maximum MCS yet */ - sched_pusch->mcs = get_mcs_from_bler(bo, stats, &UE->UE_sched_ctrl.ul_bler_stats, max_mcs, frame); + if (bo->harq_round_max == 1) + sched_pusch->mcs = max_mcs; + else + sched_pusch->mcs = get_mcs_from_bler(bo, stats, &UE->UE_sched_ctrl.ul_bler_stats, max_mcs, frame); /* Schedule UE on SR or UL inactivity and no data (otherwise, will be scheduled * based on data to transmit) */ @@ -1105,12 +1109,12 @@ void pf_ul(module_id_t module_id, const uint32_t Y = get_Y(sched_ctrl->search_space, slot, UE->rnti); uint8_t nr_of_candidates; for (int i=0; i<5; i++) { - // for now taking the lowest value among the available aggregation levels - find_aggregation_candidates(&sched_ctrl->aggregation_level, - &nr_of_candidates, - sched_ctrl->search_space, - 1<<i); - if(nr_of_candidates>0) break; + // for now taking the lowest value among the available aggregation levels + find_aggregation_candidates(&sched_ctrl->aggregation_level, + &nr_of_candidates, + sched_ctrl->search_space, + 1<<i); + if(nr_of_candidates>0) break; } int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], CC_id, @@ -1119,38 +1123,31 @@ void pf_ul(module_id_t module_id, &sched_ctrl->sched_pdcch, sched_ctrl->coreset, Y); - + if (CCEIndex<0) { - LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE->rnti); - continue; + LOG_D(NR_MAC, "%4d.%2d no free CCE for UL DCI UE %04x (BSR 0)\n", frame, slot, UE->rnti); + continue; } + /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ remainUEs--; - + + // we have filled all with mandatory retransmissions + // no need to schedule new transmissions if (remainUEs == 0) - // we have filled all with mandatory retransmissions - // no need to schedule new transmissions - return; + return; /* Save PUSCH field */ /* we want to avoid a lengthy deduction of DMRS and other parameters in - * every TTI if we can save it, so check whether dci_format, TDA, or + * every TTI if we can save it, so check whether TDA, or * num_dmrs_cdm_grps_no_data has changed and only then recompute */ const uint8_t nrOfLayers = 1; - const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_ubwp || ubwpd) ? 1 : 2; - int dci_format = get_dci_format(sched_ctrl); const int tda = get_ul_tda(nrmac, scc, sched_pusch->slot); if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format - || ps->nrOfLayers != nrOfLayers - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) { - nr_set_pusch_semi_static(sib1, + || ps->nrOfLayers != nrOfLayers) { + nr_set_pusch_semi_static(current_BWP, scc, - sched_ctrl->active_ubwp, - ubwpd, - dci_format, tda, - num_dmrs_cdm_grps_no_data, nrOfLayers, ps); } @@ -1175,7 +1172,7 @@ void pf_ul(module_id_t module_id, NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; sched_pusch->mcs = min(nrmac->min_grant_mcs, sched_pusch->mcs); - update_ul_ue_R_Qm(sched_pusch, ps); + update_ul_ue_R_Qm(sched_pusch, current_BWP->pusch_Config, current_BWP->mcs_table); sched_pusch->rbStart = rbStart; sched_pusch->rbSize = min_rb; sched_pusch->tb_size = nr_compute_tbs(sched_pusch->Qm, @@ -1198,7 +1195,7 @@ void pf_ul(module_id_t module_id, /* Create UE_sched for UEs eligibale for new data transmission*/ /* Calculate coefficient*/ - const uint32_t tbs = ul_pf_tbs[ps->mcs_table][sched_pusch->mcs]; + const uint32_t tbs = ul_pf_tbs[current_BWP->mcs_table][sched_pusch->mcs]; float coeff_ue = (float) tbs / UE->ul_thr_ue; LOG_D(NR_MAC,"rnti %04x b %d, ul_thr_ue %f, tbs %d, coeff_ue %f\n", UE->rnti, b, UE->ul_thr_ue, tbs, coeff_ue); @@ -1225,7 +1222,7 @@ void pf_ul(module_id_t module_id, sched_ctrl->search_space, 1<<i); if(nr_of_candidates>0) - break; + break; } int CCEIndex = find_pdcch_candidate(RC.nrmac[module_id], CC_id, @@ -1241,44 +1238,29 @@ void pf_ul(module_id_t module_id, } else LOG_D(NR_MAC, "%4d.%2d free CCE for UL DCI UE %04x\n",frame,slot, iterator->UE->rnti); - NR_CellGroupConfig_t *cg = iterator->UE->CellGroup; - NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated - && cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; + NR_UE_UL_BWP_t *current_BWP = &iterator->UE->current_UL_BWP; - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - scc, - sib1); - - int rbStart = sched_ctrl->active_ubwp ? NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE) : 0; - const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); + const uint16_t bwpSize = current_BWP->BWPSize; NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch; NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; /* Save PUSCH field */ /* we want to avoid a lengthy deduction of DMRS and other parameters in - * every TTI if we can save it, so check whether dci_format, TDA, or + * every TTI if we can save it, so check whether TDA, or * num_dmrs_cdm_grps_no_data has changed and only then recompute */ const uint8_t nrOfLayers = 1; - const uint8_t num_dmrs_cdm_grps_no_data = (sched_ctrl->active_ubwp || ubwpd) ? 1 : 2; - int dci_format = get_dci_format(sched_ctrl); const int tda = get_ul_tda(nrmac, scc, sched_pusch->slot); if (ps->time_domain_allocation != tda - || ps->dci_format != dci_format - || ps->nrOfLayers != nrOfLayers - || ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data) { - nr_set_pusch_semi_static(sib1, + || ps->nrOfLayers != nrOfLayers) { + nr_set_pusch_semi_static(current_BWP, scc, - sched_ctrl->active_ubwp, - ubwpd, - dci_format, tda, - num_dmrs_cdm_grps_no_data, nrOfLayers, ps); } - update_ul_ue_R_Qm(sched_pusch, ps); + update_ul_ue_R_Qm(sched_pusch, current_BWP->pusch_Config, current_BWP->mcs_table); + int rbStart = 0; const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols); while (rbStart < bwpSize && (rballoc_mask[rbStart] & slbitmap) != slbitmap) rbStart++; @@ -1326,8 +1308,8 @@ void pf_ul(module_id_t module_id, n_rb_sched -= sched_pusch->rbSize; for (int rb = 0; rb < sched_ctrl->sched_pusch.rbSize; rb++) - rballoc_mask[rb + sched_ctrl->sched_pusch.rbStart] ^= slbitmap; + /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */ remainUEs--; iterator++; @@ -1344,11 +1326,8 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t AssertFatal(scc!=NULL || scc_sib1!=NULL,"We need one serving cell config common\n"); - const int mu = scc ? scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.subcarrierSpacing : - scc_sib1->uplinkConfigCommon->initialUplinkBWP.genericParameters.subcarrierSpacing; - + // no UEs if (nr_mac->UE_info.list[0] == NULL) - // no UEs return false; const int CC_id = 0; @@ -1358,14 +1337,16 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t * TDAs yet). If the TDA is negative, it means that there is no UL slot to * schedule now (slot + k2 is not UL slot) */ NR_UE_sched_ctrl_t *sched_ctrl = &nr_mac->UE_info.list[0]->UE_sched_ctrl; + NR_UE_UL_BWP_t *current_BWP = &nr_mac->UE_info.list[0]->current_UL_BWP; + int mu = current_BWP->scs; const int temp_tda = get_ul_tda(nr_mac, scc, slot); - int K2 = get_K2(scc, scc_sib1, sched_ctrl->active_ubwp, temp_tda, mu); + int K2 = get_K2(current_BWP->tdaList, temp_tda, mu); const int sched_frame = (frame + (slot + K2 >= nr_slots_per_frame[mu])) & 1023; const int sched_slot = (slot + K2) % nr_slots_per_frame[mu]; const int tda = get_ul_tda(nr_mac, scc, sched_slot); if (tda < 0) return false; - DevAssert(K2 == get_K2(scc, scc_sib1, sched_ctrl->active_ubwp, tda, mu)); + DevAssert(K2 == get_K2(current_BWP->tdaList, tda, mu)); if (!is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot)) return false; @@ -1379,7 +1360,7 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t is_xlsch_in_slot(nr_mac->ulsch_slot_bitmap[sched_slot / 64], sched_slot); // FIXME: Avoid mixed slots for initialUplinkBWP - if (sched_ctrl->active_ubwp==NULL && is_mixed_slot) + if (current_BWP->bwp_id==0 && is_mixed_slot) return false; // Avoid slots with the SRS @@ -1394,9 +1375,9 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t sched_ctrl->sched_pusch.frame = sched_frame; UE_iterator(nr_mac->UE_info.list, UE2) { NR_UE_sched_ctrl_t *sched_ctrl = &UE2->UE_sched_ctrl; - AssertFatal(K2 == get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), + AssertFatal(K2 == get_K2(current_BWP->tdaList, tda, mu), "Different K2, %d(UE%d) != %ld(UE%04x)\n", - K2, 0, get_K2(scc,scc_sib1,sched_ctrl->active_ubwp, tda, mu), UE2->rnti); + K2, 0, get_K2(current_BWP->tdaList, tda, mu), UE2->rnti); sched_ctrl->sched_pusch.slot = sched_slot; sched_ctrl->sched_pusch.frame = sched_frame; } @@ -1407,24 +1388,10 @@ bool nr_fr1_ulsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t uint16_t *vrb_map_UL = &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[sched_slot * MAX_BWP_SIZE]; - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - scc, - sib1); - - const uint16_t bwpSize = NRRIV2BW(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - const uint16_t bwpStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,MAX_BWP_SIZE); - - NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList = NULL; - if (sched_ctrl->active_ubwp) { - tdaList = sched_ctrl->active_ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else if (scc) { - tdaList = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } else { - NR_SIB1_t *sib1 = RC.nrmac[module_id]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1; - tdaList = sib1->servingCellConfigCommon->uplinkConfigCommon->initialUplinkBWP.pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList; - } + const uint16_t bwpSize = current_BWP->BWPSize; + const uint16_t bwpStart = current_BWP->BWPStart; - const int startSymbolAndLength = tdaList->list.array[tda]->startSymbolAndLength; + const int startSymbolAndLength = current_BWP->tdaList->list.array[tda]->startSymbolAndLength; int startSymbolIndex, nrOfSymbols; SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols); const uint16_t symb = SL_to_bitmap(startSymbolIndex, nrOfSymbols); @@ -1524,10 +1491,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) if (sched_ctrl->ul_failure == 1 && get_softmodem_params()->phy_test==0) continue; NR_CellGroupConfig_t *cg = UE->CellGroup; - - NR_BWP_UplinkDedicated_t *ubwpd = cg && cg->spCellConfig && cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig ? - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP : NULL; + NR_UE_UL_BWP_t *current_BWP = &UE->current_UL_BWP; UE->mac_stats.ul.current_bytes = 0; @@ -1573,7 +1537,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) NR_pusch_semi_static_t *ps = &sched_ctrl->pusch_semi_static; /* Statistics */ - AssertFatal(cur_harq->round < 8, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round); + AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing ulsch_rounds[%d] is out of bounds\n", cur_harq->round); UE->mac_stats.ul.rounds[cur_harq->round]++; if (cur_harq->round == 0) { UE->mac_stats.ulsch_total_bytes_scheduled += sched_pusch->tb_size; @@ -1619,7 +1583,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) sched_pusch->tb_size, harq_id, cur_harq->round, - nr_rv_round_map[cur_harq->round], + nr_rv_round_map[cur_harq->round%4], cur_harq->ndi, sched_ctrl->estimated_ul_buffer, sched_ctrl->sched_ul_bytes, @@ -1653,23 +1617,20 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->handle = 0; //not yet used /* FAPI: BWP */ - NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp, - scc, - sib1); - pusch_pdu->bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - pusch_pdu->bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE); - pusch_pdu->subcarrier_spacing = genericParameters->subcarrierSpacing; + pusch_pdu->bwp_size = current_BWP->BWPSize; + pusch_pdu->bwp_start = current_BWP->BWPStart; + pusch_pdu->subcarrier_spacing = current_BWP->scs; pusch_pdu->cyclic_prefix = 0; /* FAPI: PUSCH information always included */ pusch_pdu->target_code_rate = sched_pusch->R; pusch_pdu->qam_mod_order = sched_pusch->Qm; pusch_pdu->mcs_index = sched_pusch->mcs; - pusch_pdu->mcs_table = ps->mcs_table; - pusch_pdu->transform_precoding = ps->transform_precoding; - if (ps->pusch_Config && ps->pusch_Config->dataScramblingIdentityPUSCH) - pusch_pdu->data_scrambling_id = *ps->pusch_Config->dataScramblingIdentityPUSCH; + pusch_pdu->mcs_table = current_BWP->mcs_table; + pusch_pdu->transform_precoding = current_BWP->transform_precoding; + if (current_BWP->pusch_Config && current_BWP->pusch_Config->dataScramblingIdentityPUSCH) + pusch_pdu->data_scrambling_id = *current_BWP->pusch_Config->dataScramblingIdentityPUSCH; else pusch_pdu->data_scrambling_id = *scc->physCellId; pusch_pdu->nrOfLayers = ps->nrOfLayers; @@ -1705,7 +1666,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->rb_start = sched_pusch->rbStart; pusch_pdu->rb_size = sched_pusch->rbSize; pusch_pdu->vrb_to_prb_mapping = 0; - if (ps->pusch_Config==NULL || ps->pusch_Config->frequencyHopping==NULL) + if (current_BWP->pusch_Config==NULL || current_BWP->pusch_Config->frequencyHopping==NULL) pusch_pdu->frequency_hopping = 0; else pusch_pdu->frequency_hopping = 1; @@ -1715,8 +1676,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) pusch_pdu->nr_of_symbols = ps->nrOfSymbols; /* PUSCH PDU */ - AssertFatal(cur_harq->round < 4, "Indexing nr_rv_round_map[%d] is out of bounds\n", cur_harq->round); - pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round]; + AssertFatal(cur_harq->round < nr_mac->ul_bler.harq_round_max, "Indexing nr_rv_round_map[%d] is out of bounds\n", cur_harq->round%4); + pusch_pdu->pusch_data.rv_index = nr_rv_round_map[cur_harq->round%4]; pusch_pdu->pusch_data.harq_process_id = harq_id; pusch_pdu->pusch_data.new_data_indicator = cur_harq->ndi; pusch_pdu->pusch_data.tb_size = sched_pusch->tb_size; @@ -1739,7 +1700,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) else AssertFatal(1==0,"SequenceGroupHopping or sequenceHopping are NOT Supported\n"); - LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d MCS table: %d\n", pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dfts_ofdm.low_papr_group_number, ps->mcs_table); + LOG_D(NR_MAC,"TRANSFORM PRECODING IS ENABLED. CDM groups: %d, U: %d MCS table: %d\n", pusch_pdu->num_dmrs_cdm_grps_no_data, pusch_pdu->dfts_ofdm.low_papr_group_number, current_BWP->mcs_table); } /*-----------------------------------------------------------------------------*/ @@ -1763,9 +1724,8 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) /* look up the PDCCH PDU for this BWP and CORESET. If it does not exist, * create it */ - const int bwp_id = sched_ctrl->active_bwp ? sched_ctrl->active_bwp->bwp_Id : 0; - NR_SearchSpace_t *ss = (sched_ctrl->active_bwp || ubwpd) ? sched_ctrl->search_space: RC.nrmac[module_id]->sched_ctrlCommon->search_space; - NR_ControlResourceSet_t *coreset = (sched_ctrl->active_bwp || ubwpd) ? sched_ctrl->coreset: RC.nrmac[module_id]->sched_ctrlCommon->coreset; + NR_SearchSpace_t *ss = sched_ctrl->search_space; + NR_ControlResourceSet_t *coreset = sched_ctrl->coreset; const int coresetid = coreset->controlResourceSetId; nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu = pdcch_pdu_coreset[coresetid]; if (!pdcch_pdu) { @@ -1775,7 +1735,7 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) ul_dci_request_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); pdcch_pdu = &ul_dci_request_pdu->pdcch_pdu.pdcch_pdu_rel15; ul_dci_req->numPdus += 1; - nr_configure_pdcch(pdcch_pdu, coreset, genericParameters, &sched_ctrl->sched_pdcch); + nr_configure_pdcch(pdcch_pdu, coreset, false, &sched_ctrl->sched_pdcch); pdcch_pdu_coreset[coresetid] = pdcch_pdu; } @@ -1800,35 +1760,24 @@ void nr_schedule_ulsch(module_id_t module_id, frame_t frame, sub_frame_t slot) dci_pdu_rel15_t uldci_payload; memset(&uldci_payload, 0, sizeof(uldci_payload)); - int n_ubwp=1; - if (cg && - cg->spCellConfig && - cg->spCellConfig->spCellConfigDedicated && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig && - cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList) { - n_ubwp = cg->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.count; - } config_uldci(sib1, - sched_ctrl->active_ubwp, - ubwpd, scc, pusch_pdu, &uldci_payload, - ps->dci_format, ps->time_domain_allocation, UE->UE_sched_ctrl.tpc0, - n_ubwp, - bwp_id); + current_BWP); fill_dci_pdu_rel15(scc, cg, + &UE->current_DL_BWP, dci_pdu, &uldci_payload, - ps->dci_format, + current_BWP->dci_format, rnti_types[0], pusch_pdu->bwp_size, - bwp_id, - coresetid, + current_BWP->bwp_id, + coreset, nr_mac->cset0_bwp_size); memset(sched_pusch, 0, sizeof(*sched_pusch)); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 7911275f70fff04c0c79b0e120a8fb8813d4a455..674d80a4d43f71a0a441f2fd70241852ede8d408 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -36,12 +36,9 @@ void set_cset_offset(uint16_t); -void mac_top_init_gNB(void); - -void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl); +void mac_top_init_gNB(ngran_node_t node_type); void config_common(int Mod_idP, - int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc); @@ -52,7 +49,6 @@ int nr_mac_enable_ue_rrc_processing_timer(module_id_t Mod_idP, uint32_t rrc_reconfiguration_delay); int rrc_mac_config_req_gNB(module_id_t Mod_idP, - int ssb_SubcarrierOffset, rrc_pdsch_AntennaPorts_t pdsch_AntennaPorts, int pusch_AntennaPorts, int sib1_tda, @@ -95,7 +91,7 @@ uint32_t schedule_control_sib1(module_id_t module_id, int nrOfSymbols, uint16_t dlDmrsSymbPos, uint8_t candidate_idx, - int num_total_bytes); + uint16_t num_total_bytes); /* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */ nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(module_id_t module_id, int CC_id); @@ -134,7 +130,6 @@ int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slo void nr_get_Msg3alloc(module_id_t module_id, int CC_id, NR_ServingCellConfigCommon_t *scc, - NR_BWP_Uplink_t *ubwp, sub_frame_t current_subframe, frame_t current_frame, NR_RA_t *ra, @@ -192,18 +187,14 @@ void handle_nr_uci_pucch_2_3_4(module_id_t mod_id, void config_uldci(const NR_SIB1_t *sib1, - const NR_BWP_Uplink_t *ubwp, - const NR_BWP_UplinkDedicated_t *ubwpd, const NR_ServingCellConfigCommon_t *scc, const nfapi_nr_pusch_pdu_t *pusch_pdu, dci_pdu_rel15_t *dci_pdu_rel15, - int dci_format, int time_domain_assignment, uint8_t tpc, - int n_ubwp, - int bwp_id); + NR_UE_UL_BWP_t *ul_bwp); -void nr_schedule_pucch(gNB_MAC_INST* nrmac, +void nr_schedule_pucch(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP); @@ -218,16 +209,15 @@ void nr_csi_meas_reporting(int Mod_idP, frame_t frameP, sub_frame_t slotP); -int nr_acknack_scheduling( int Mod_idP, - NR_UE_info_t * UE, - frame_t frameP, - sub_frame_t slotP, - int r_pucch, - int do_common); +int nr_acknack_scheduling(int Mod_idP, + NR_UE_info_t *UE, + frame_t frameP, + sub_frame_t slotP, + int r_pucch, + int do_common); -void get_pdsch_to_harq_feedback(NR_UE_info_t *, - int bwp_id, - NR_SearchSpace__searchSpaceType_PR ss_type, +void get_pdsch_to_harq_feedback(NR_PUCCH_Config_t *pucch_Config, + nr_dci_format_t dci_format, int *max_fb_time, uint8_t *pdsch_to_harq_feedback); @@ -251,17 +241,12 @@ int nr_is_dci_opportunity(nfapi_nr_search_space_t search_space, */ int nr_get_pucch_resource(NR_ControlResourceSet_t *coreset, - NR_BWP_Uplink_t *bwp, - NR_BWP_UplinkDedicated_t *bwpd, + NR_PUCCH_Config_t *pucch_Config, int CCEIndex); -void nr_configure_pucch(const NR_SIB1_t *sib1, - nfapi_nr_pucch_pdu_t* pucch_pdu, +void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, NR_ServingCellConfigCommon_t *scc, - NR_CellGroupConfig_t *CellGroup, - NR_BWP_Uplink_t *bwp, - NR_BWP_UplinkDedicated_t *bwpd, - uint16_t rnti, + NR_UE_info_t* UE, uint8_t pucch_resource, uint16_t O_csi, uint16_t O_ack, @@ -274,7 +259,7 @@ void find_search_space(int ss_type, void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu, NR_ControlResourceSet_t *coreset, - NR_BWP_t *bwp, + bool is_sib1, NR_sched_pdcch_t *pdcch); NR_sched_pdcch_t set_pdcch_structure(gNB_MAC_INST *gNB_mac, @@ -300,19 +285,21 @@ void fill_pdcch_vrb_map(gNB_MAC_INST *mac, void fill_dci_pdu_rel15(const NR_ServingCellConfigCommon_t *scc, const NR_CellGroupConfig_t *CellGroup, + const NR_UE_DL_BWP_t *dl_bwp, nfapi_nr_dl_dci_pdu_t *pdcch_dci_pdu, dci_pdu_rel15_t *dci_pdu_rel15, int dci_formats, int rnti_types, int N_RB, int bwp_id, - NR_ControlResourceSetId_t coreset_id, + NR_ControlResourceSet_t *coreset, uint16_t cset0_bwp_size); void prepare_dci(const NR_CellGroupConfig_t *CellGroup, + const NR_UE_DL_BWP_t *dl_bwp, + const NR_ControlResourceSet_t *coreset, dci_pdu_rel15_t *dci_pdu_rel15, - nr_dci_format_t format, - int bwp_id); + nr_dci_format_t format); void set_r_pucch_parms(int rsetindex, int r_pucch, @@ -322,18 +309,6 @@ void set_r_pucch_parms(int rsetindex, int *nr_of_symbols, int *start_symbol_index); -NR_BWP_t *get_dl_bwp_genericParameters(NR_BWP_Downlink_t *active_bwp, - NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1); - -NR_BWP_t *get_ul_bwp_genericParameters(NR_BWP_Uplink_t *active_ubwp, - NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1); - -NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(const NR_BWP_Downlink_t *active_bwp, - const NR_ServingCellConfigCommon_t *ServingCellConfigCommon, - const NR_SIB1_t *sib1); - /* find coreset within the search space */ NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, NR_ServingCellConfigCommon_t *scc, @@ -342,34 +317,24 @@ NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac, NR_SearchSpace__searchSpaceType_PR ss_type); /* find a search space within a BWP */ -NR_SearchSpace_t *get_searchspace(const NR_SIB1_t *sib1, - NR_ServingCellConfigCommon_t *scc, +NR_SearchSpace_t *get_searchspace(NR_ServingCellConfigCommon_t *scc, NR_BWP_DownlinkDedicated_t *bwp_Dedicated, NR_SearchSpace__searchSpaceType_PR target_ss); -long get_K2(NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfigCommonSIB_t *scc_sib1, - NR_BWP_Uplink_t *ubwp, +long get_K2(NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList, int time_domain_assignment, int mu); -void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1, +void nr_set_pdsch_semi_static(const NR_UE_DL_BWP_t *dl_bwp, const NR_ServingCellConfigCommon_t *scc, - const NR_CellGroupConfig_t *secondaryCellGroup, - const NR_BWP_Downlink_t *bwp, - const NR_BWP_DownlinkDedicated_t *bwpd0, int tda, uint8_t layers, NR_UE_sched_ctrl_t *sched_ctrl, NR_pdsch_semi_static_t *ps); -void nr_set_pusch_semi_static(const NR_SIB1_t *sib1, +void nr_set_pusch_semi_static(const NR_UE_UL_BWP_t *ul_bwp, const NR_ServingCellConfigCommon_t *scc, - const NR_BWP_Uplink_t *ubwp, - const NR_BWP_UplinkDedicated_t *ubwpd, - long dci_format, int tda, - uint8_t num_dmrs_cdm_grps_no_data, uint8_t nrOfLayers, NR_pusch_semi_static_t *ps); @@ -404,7 +369,13 @@ NR_UE_info_t * find_nr_UE(NR_UEs_t* UEs, rnti_t rntiP); int find_nr_RA_id(module_id_t mod_idP, int CC_idP, rnti_t rntiP); -NR_UE_info_t*add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup); +void configure_UE_BWP(gNB_MAC_INST *nr_mac, + NR_ServingCellConfigCommon_t *scc, + NR_UE_sched_ctrl_t *sched_ctrl, + NR_RA_t *ra, + NR_UE_info_t *UE); + +NR_UE_info_t* add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConfig_t *CellGroup); void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti); @@ -412,24 +383,12 @@ void nr_mac_remove_ra_rnti(module_id_t mod_id, rnti_t rnti); int nr_get_default_pucch_res(int pucch_ResourceCommon); -void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE); - int get_dlscs(nfapi_nr_config_request_t *cfg); int get_ulscs(nfapi_nr_config_request_t *cfg); int get_symbolsperslot(nfapi_nr_config_request_t *cfg); -void config_nr_mib(int Mod_idP, - int CC_idP, - int p_gNBP, - int subCarrierSpacingCommon, - uint32_t ssb_SubcarrierOffset, - int dmrs_TypeA_Position, - uint32_t pdcch_ConfigSIB1, - int cellBarred, - int intraFreqReselection); - int nr_write_ce_dlsch_pdu(module_id_t module_idP, const NR_UE_sched_ctrl_t *ue_sched_ctl, unsigned char *mac_pdu, @@ -446,7 +405,7 @@ int binomial(int n, int k); bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot); -void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id); +void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int ssb_subcarrier_offset, uint16_t symStart, int CC_id); /* \brief Function to indicate a received SDU on ULSCH. @@ -482,9 +441,19 @@ void handle_nr_ul_harq(const int CC_idP, sub_frame_t slot, const nfapi_nr_crc_t *crc_pdu); +void handle_nr_srs_measurements(const module_id_t module_id, + const frame_t frame, + const sub_frame_t slot, + const rnti_t rnti, + const uint16_t timing_advance, + const uint8_t num_symbols, + const uint8_t wide_band_snr, + const uint8_t num_reported_symbols, + nfapi_nr_srs_indication_reported_symbol_t* reported_symbol_list); + int16_t ssb_index_from_prach(module_id_t module_idP, frame_t frameP, - sub_frame_t slotP, + sub_frame_t slotP, uint16_t preamble_index, uint8_t freq_index, uint8_t symbol); @@ -503,7 +472,6 @@ uint8_t get_mcs_from_cqi(int mcs_table, int cqi_table, int cqi_idx); uint8_t set_dl_nrOfLayers(NR_UE_sched_ctrl_t *sched_ctrl); -int get_dci_format(NR_UE_sched_ctrl_t *sched_ctrl); const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot); const int get_ul_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon_t *scc, int slot); @@ -526,10 +494,21 @@ int get_mcs_from_bler(const NR_bler_options_t *bler_options, int max_mcs, frame_t frame); +void UL_tti_req_ahead_initialization(gNB_MAC_INST * gNB, NR_ServingCellConfigCommon_t *scc, int n, int CCid); + void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t frameP, sub_frame_t slotP); size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset_rsrp); void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_sched_ctrl_t *sched_ctrl); +void send_initial_ul_rrc_message(module_id_t module_id, + int CC_id, + const NR_UE_info_t *UE, + rb_id_t srb_id, + const uint8_t *sdu, + sdu_size_t sdu_len); + +void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid); + #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c new file mode 100644 index 0000000000000000000000000000000000000000..578e4fb4535209e9c7684d709446f946936f7c65 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -0,0 +1,131 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "mac_rrc_dl_handler.h" + +#include "mac_proto.h" +#include "openair2/RRC/NR/rrc_gNB_UE_context.h" + +#include "NR_RRCSetup.h" +#include "NR_DL-CCCH-Message.h" +#include "NR_CellGroupConfig.h" + +int dl_rrc_message_rrcSetup(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc, NR_RRCSetup_t *rrcSetup); + +int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) +{ + /* dispatch message to dl_rrc_message_rrcSetup() and others, similar to as is + * done in the DU (should be the same here) */ + + if (dl_rrc->srb_id == 0) { + + NR_DL_CCCH_Message_t *dl_ccch_msg = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_DL_CCCH_Message, + (void **) &dl_ccch_msg, + dl_rrc->rrc_container, + dl_rrc->rrc_container_length, + 0, + 0); + AssertFatal(dec_rval.code == RC_OK, "could not decode F1AP message\n"); + + switch (dl_ccch_msg->message.choice.c1->present) { + case NR_DL_CCCH_MessageType__c1_PR_NOTHING: + LOG_W(NR_MAC, "Received NOTHING on DL-CCCH-Message\n"); + break; + case NR_DL_CCCH_MessageType__c1_PR_rrcReject: + LOG_D(NR_MAC, "DL-CCCH/SRB0, received rrcReject for RNTI %04x\n", dl_rrc->rnti); + AssertFatal(0, "rrcReject not implemented yet\n"); + break; + case NR_DL_CCCH_MessageType__c1_PR_rrcSetup: + LOG_I(NR_MAC, "DL-CCCH/SRB0, received rrcSetup for RNTI %04x\n", dl_rrc->rnti); + return dl_rrc_message_rrcSetup(module_id, dl_rrc, dl_ccch_msg->message.choice.c1->choice.rrcSetup); + break; + case NR_DL_CCCH_MessageType__c1_PR_spare2: + LOG_W(NR_MAC, "DL-CCCH/SRB0, received spare2\n"); + break; + case NR_DL_CCCH_MessageType__c1_PR_spare1: + LOG_W(NR_MAC, "DL-CCCH/SRB0, received spare1\n"); + break; + default: + AssertFatal(0 == 1, "Unknown DL-CCCH/SRB0 message %d\n", dl_ccch_msg->message.choice.c1->present); + break; + } + return 0; + } + + return -1; /* not handled yet */ +} + +int dl_rrc_message_rrcSetup(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc, NR_RRCSetup_t *rrcSetup) +{ + DevAssert(rrcSetup != NULL); + + NR_RRCSetup_IEs_t *rrcSetup_ies = rrcSetup->criticalExtensions.choice.rrcSetup; + AssertFatal(rrcSetup_ies->masterCellGroup.buf != NULL,"masterCellGroup is NULL\n"); + NR_CellGroupConfig_t *cellGroup = NULL; + asn_dec_rval_t dec_rval = uper_decode(NULL, + &asn_DEF_NR_CellGroupConfig, + (void **)&cellGroup, + rrcSetup_ies->masterCellGroup.buf, + rrcSetup_ies->masterCellGroup.size, + 0, + 0); + AssertFatal(dec_rval.code == RC_OK, "could not decode masterCellGroup\n"); + + /* there might be a memory leak for the cell group if we call this multiple + * times. Also, the first parameters of rrc_mac_config_req_gNB() are only + * relevant when setting the scc, which we don't do (and cannot do) here. */ + rrc_pdsch_AntennaPorts_t pap = {0}; + rrc_mac_config_req_gNB(module_id, + pap, /* only when scc != NULL */ + 0, /* only when scc != NULL */ + 0, /* only when scc != NULL */ + 0, /* only when scc != NULL */ + NULL, /* scc */ + NULL, /* mib */ + NULL, /* sib1 */ + 0, /* add_ue */ + dl_rrc->rnti, + cellGroup); + + /* TODO: drop the RRC context */ + gNB_RRC_INST *rrc = RC.nrrrc[module_id]; + struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, dl_rrc->rnti); + gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; + ue_context_p->ue_context.SRB_configList = rrcSetup_ies->radioBearerConfig.srb_ToAddModList; + ue_context_p->ue_context.masterCellGroup = cellGroup; + + /* TODO: this should pass through RLC and NOT the RRC with a shared buffer */ + AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n"); + memcpy(ue_p->Srb0.Tx_buffer.Payload, dl_rrc->rrc_container, dl_rrc->rrc_container_length); + ue_p->Srb0.Tx_buffer.payload_size = dl_rrc->rrc_container_length; + + protocol_ctxt_t ctxt = { .module_id = module_id, .rnti = dl_rrc->rnti }; + nr_rrc_rlc_config_asn1_req(&ctxt, + ue_context_p->ue_context.SRB_configList, + NULL, + NULL, + NULL, + cellGroup->rlc_BearerToAddModList); + + return 0; +} diff --git a/openair2/COMMON/itti_sim_messages_def.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h similarity index 59% rename from openair2/COMMON/itti_sim_messages_def.h rename to openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index 681fc932dd2d6d3b593d8360f140a415e80dd371..ecbc95eef07190ea4fee1976f2a953c4e3040894 100644 --- a/openair2/COMMON/itti_sim_messages_def.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -19,18 +19,12 @@ * contact@openairinterface.org */ -/*! \file itti_sim_messages_def.h - * \brief itti message for itti simulator - * \author Yoshio INOUE, Masayuki HARADA - * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com - * \date 2020 - * \version 0.1 - */ +#ifndef MAC_RRC_DL_HANDLER_H +#define MAC_RRC_DL_HANDLER_H +#include "platform_types.h" +#include "f1ap_messages_types.h" +int dl_rrc_message(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); -MESSAGE_DEF(GNB_RRC_BCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBBCCHind) -MESSAGE_DEF(GNB_RRC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBCCCHind) -MESSAGE_DEF(GNB_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, GNBDCCHind) -MESSAGE_DEF(UE_RRC_CCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, UECCCHind) -MESSAGE_DEF(UE_RRC_DCCH_DATA_IND, MESSAGE_PRIORITY_MED, itti_sim_rrc_ch_t, UEDCCHind) +#endif /* MAC_RRC_DL_HANDLER_H */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h new file mode 100644 index 0000000000000000000000000000000000000000..cb80ba4fa55c1f5c3a6ba9df5e6a41b546a3a850 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h @@ -0,0 +1,34 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * conmnc_digit_lengtht@openairinterface.org + */ + +#ifndef MAC_RRC_UL_H +#define MAC_RRC_UL_H + +#include "platform_types.h" +#include "f1ap_messages_types.h" + +typedef void (*initial_ul_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc); + +struct nr_mac_rrc_ul_if_s; +void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc); +void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc); + +#endif /* MAC_RRC_UL_H */ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c new file mode 100644 index 0000000000000000000000000000000000000000..25ee7feb14a6934ecaab1d23ea4d16e758d49552 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c @@ -0,0 +1,49 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include "nr_mac_gNB.h" + +#include "mac_rrc_ul.h" + +static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + /* copy all fields, but reallocate rrc_containers! */ + f1ap_initial_ul_rrc_message_t *f1ap_msg = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); + *f1ap_msg = *ul_rrc; + + f1ap_msg->rrc_container = malloc(ul_rrc->rrc_container_length); + DevAssert(f1ap_msg->rrc_container); + memcpy(f1ap_msg->rrc_container, ul_rrc->rrc_container, ul_rrc->rrc_container_length); + f1ap_msg->rrc_container_length = ul_rrc->rrc_container_length; + + f1ap_msg->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); + DevAssert(f1ap_msg->du2cu_rrc_container); + memcpy(f1ap_msg->du2cu_rrc_container, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length); + f1ap_msg->du2cu_rrc_container_length = ul_rrc->du2cu_rrc_container_length; + + itti_send_msg_to_task(TASK_RRC_GNB, module_id, msg); +} + +void mac_rrc_ul_direct_init(struct nr_mac_rrc_ul_if_s *mac_rrc) +{ + mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_direct; +} diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c new file mode 100644 index 0000000000000000000000000000000000000000..65e7f10405eabab771701b4a6d15a94908ec0724 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -0,0 +1,50 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include "nr_mac_gNB.h" + +#include "mac_rrc_ul.h" + +static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *ul_rrc) +{ + MessageDef *msg = itti_alloc_new_message(TASK_MAC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE); + /* copy all fields, but reallocate rrc_containers! */ + f1ap_initial_ul_rrc_message_t *f1ap_msg = &F1AP_INITIAL_UL_RRC_MESSAGE(msg); + *f1ap_msg = *ul_rrc; + + f1ap_msg->rrc_container = malloc(ul_rrc->rrc_container_length); + DevAssert(f1ap_msg->rrc_container); + memcpy(f1ap_msg->rrc_container, ul_rrc->rrc_container, ul_rrc->rrc_container_length); + f1ap_msg->rrc_container_length = ul_rrc->rrc_container_length; + + f1ap_msg->du2cu_rrc_container = malloc(ul_rrc->du2cu_rrc_container_length); + DevAssert(f1ap_msg->du2cu_rrc_container); + memcpy(f1ap_msg->du2cu_rrc_container, ul_rrc->du2cu_rrc_container, ul_rrc->du2cu_rrc_container_length); + f1ap_msg->du2cu_rrc_container_length = ul_rrc->du2cu_rrc_container_length; + + itti_send_msg_to_task(TASK_DU_F1, module_id, msg); +} + +void mac_rrc_ul_f1ap_init(struct nr_mac_rrc_ul_if_s *mac_rrc) +{ + mac_rrc->initial_ul_rrc_message_transfer = initial_ul_rrc_message_transfer_f1ap; +} + diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 9b9fd4e76cbed3900730877eca4af3d13ecde5c0..8c1abf4561abe7ebf7b86b08fa53545a64f23830 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -84,38 +84,42 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset int num = 1; const char *begin = output; const char *end = output + strlen; - + pthread_mutex_lock(&gNB->UE_info.mutex); UE_iterator(gNB->UE_info.list, UE) { NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl; NR_mac_stats_t *stats = &UE->mac_stats; const int avg_rsrp = stats->num_rsrp_meas > 0 ? stats->cumul_rsrp / stats->num_rsrp_meas : 0; - output += snprintf(output, end - output, - "UE RNTI %04x (%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas)\n", + "UE RNTI %04x (%d) PH %d dB PCMAX %d dBm, average RSRP %d (%d meas), UL-SNR %d dB\n", UE->rnti, num++, sched_ctrl->ph, sched_ctrl->pcmax, avg_rsrp, - stats->num_rsrp_meas); + stats->num_rsrp_meas, + stats->srs_wide_band_snr); output += snprintf(output, end - output, "UE %04x: CQI %d, RI %d, PMI (%d,%d)\n", UE->rnti, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.ri+1, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1, - UE->UE_sched_ctrl.CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2); + sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.wb_cqi_1tb, + sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.ri+1, + sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x1, + sched_ctrl->CSI_report.cri_ri_li_pmi_cqi_report.pmi_x2); output += snprintf(output, end - output, - "UE %04x: dlsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n", - UE->rnti, - stats->dl.rounds[0], stats->dl.rounds[1], - stats->dl.rounds[2], stats->dl.rounds[3], + "UE %04x: dlsch_rounds ", UE->rnti); + output += snprintf(output, end - output, "%"PRIu64, stats->dl.rounds[0]); + for (int i = 1; i < gNB->dl_bler.harq_round_max; i++) + output += snprintf(output, end - output, "/%"PRIu64, stats->dl.rounds[i]); + + output += snprintf(output, + end - output, + ", dlsch_errors %"PRIu64", pucch0_DTX %d, BLER %.5f MCS %d\n", stats->dl.errors, stats->pucch0_DTX, sched_ctrl->dl_bler_stats.bler, @@ -127,23 +131,27 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset output += snprintf(output, end - output, "UE %04x: dlsch_total_bytes %"PRIu64"\n", - UE->rnti, - stats->dl.total_bytes); + UE->rnti, stats->dl.total_bytes); output += snprintf(output, end - output, - "UE %04x: ulsch_rounds %"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n", - UE->rnti, - stats->ul.rounds[0], stats->ul.rounds[1], - stats->ul.rounds[2], stats->ul.rounds[3], + "UE %04x: ulsch_rounds ", UE->rnti); + output += snprintf(output, end - output, "%"PRIu64, stats->ul.rounds[0]); + for (int i = 1; i < gNB->ul_bler.harq_round_max; i++) + output += snprintf(output, end - output, "/%"PRIu64, stats->ul.rounds[i]); + + output += snprintf(output, + end - output, + ", ulsch_DTX %d, ulsch_errors %"PRIu64", BLER %.5f MCS %d\n", stats->ulsch_DTX, stats->ul.errors, sched_ctrl->ul_bler_stats.bler, sched_ctrl->ul_bler_stats.mcs); output += snprintf(output, end - output, - "UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n", - UE->rnti, - stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes); + "UE %04x: ulsch_total_bytes_scheduled %"PRIu64", ulsch_total_bytes_received %"PRIu64"\n", + UE->rnti, + stats->ulsch_total_bytes_scheduled, stats->ul.total_bytes); + for (int lc_id = 0; lc_id < 63; lc_id++) { if (stats->dl.lc_bytes[lc_id] > 0) output += snprintf(output, @@ -165,8 +173,25 @@ size_t dump_mac_stats(gNB_MAC_INST *gNB, char *output, size_t strlen, bool reset return output - begin; } +static void mac_rrc_init(gNB_MAC_INST *mac, ngran_node_t node_type) +{ + switch (node_type) { + case ngran_gNB_CU: + AssertFatal(1 == 0, "nothing to do for CU\n"); + break; + case ngran_gNB_DU: + mac_rrc_ul_f1ap_init(&mac->mac_rrc); + break; + case ngran_gNB: + mac_rrc_ul_direct_init(&mac->mac_rrc); + break; + default: + AssertFatal(0 == 1, "Unknown node type %d\n", node_type); + break; + } +} -void mac_top_init_gNB(void) +void mac_top_init_gNB(ngran_node_t node_type) { module_id_t i; gNB_MAC_INST *nrmac; @@ -203,6 +228,7 @@ void mac_top_init_gNB(void) RC.nrmac[i]->first_MIB = true; pthread_mutex_init(&RC.nrmac[i]->UE_info.mutex, NULL); + uid_linear_allocator_init(&RC.nrmac[i]->UE_info.uid_allocator); if (get_softmodem_params()->phy_test) { RC.nrmac[i]->pre_processor_dl = nr_preprocessor_phytest; @@ -211,8 +237,10 @@ void mac_top_init_gNB(void) RC.nrmac[i]->pre_processor_dl = nr_init_fr1_dlsch_preprocessor(i, 0); RC.nrmac[i]->pre_processor_ul = nr_init_fr1_ulsch_preprocessor(i, 0); } - pthread_create(&RC.nrmac[i]->stats_thread,NULL,nrmac_stats_thread,(void*)RC.nrmac[i]); + if (!IS_SOFTMODEM_NOSTATS_BIT) + pthread_create(&RC.nrmac[i]->stats_thread, NULL, nrmac_stats_thread, (void*)RC.nrmac[i]); + mac_rrc_init(RC.nrmac[i], node_type); }//END for (i = 0; i < RC.nb_nr_macrlc_inst; i++) AssertFatal(rlc_module_init(1) == 0,"Could not initialize RLC layer\n"); @@ -232,7 +260,6 @@ void mac_top_init_gNB(void) // Initialize Linked-List for Active UEs for (i = 0; i < RC.nb_nr_macrlc_inst; i++) { - nrmac = RC.nrmac[i]; nrmac->if_inst = NR_IF_Module_init(i); memset(&nrmac->UE_info, 0, sizeof(nrmac->UE_info)); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 7658441aed63941282b248dc53f2e04f6fcfaa38..09f3193790b01c2564f723453ac2f1372abeeac0 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -46,6 +46,7 @@ #include "targets/ARCH/COMMON/common_lib.h" #include "COMMON/platform_constants.h" #include "common/ran_context.h" +#include "collection/linear_alloc.h" /* RRC */ #include "NR_BCCH-BCH-Message.h" @@ -60,6 +61,7 @@ /* Interface */ #include "nfapi_nr_interface_scf.h" #include "NR_PHY_INTERFACE/NR_IF_Module.h" +#include "mac_rrc_ul.h" /* MAC */ #include "LAYER2/MAC/mac.h" @@ -75,7 +77,6 @@ #define MAX_NUM_BWP 5 #define MAX_NUM_CORESET 12 #define MAX_NUM_CCE 90 -#define MAX_HARQ_ROUNDS 4 /*!\brief Maximum number of random access process */ #define NR_NB_RA_PROC_MAX 4 #define MAX_NUM_OF_SSB 64 @@ -91,6 +92,37 @@ typedef struct { int len; } NR_list_t; +typedef struct NR_UE_DL_BWP { + NR_BWP_Id_t bwp_id; + int n_dl_bwp; + int scs; + long *cyclicprefix; + uint16_t BWPSize; + uint16_t BWPStart; + NR_PDSCH_TimeDomainResourceAllocationList_t *tdaList; + NR_PDSCH_Config_t *pdsch_Config; + NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig; + uint8_t mcsTableIdx; + nr_dci_format_t dci_format; +} NR_UE_DL_BWP_t; + +typedef struct NR_UE_UL_BWP { + NR_BWP_Id_t bwp_id; + int n_ul_bwp; + int scs; + long *cyclicprefix; + uint16_t BWPSize; + uint16_t BWPStart; + NR_PUSCH_TimeDomainResourceAllocationList_t *tdaList; + NR_PUSCH_Config_t *pusch_Config; + NR_PUCCH_Config_t *pucch_Config; + NR_PUCCH_ConfigCommon_t *pucch_ConfigCommon; + NR_CSI_MeasConfig_t *csi_MeasConfig; + NR_SRS_Config_t *srs_Config; + uint8_t transform_precoding; + uint8_t mcs_table; + nr_dci_format_t dci_format; +} NR_UE_UL_BWP_t; typedef enum { RA_IDLE = 0, @@ -124,10 +156,6 @@ typedef struct NR_sched_pdcch { typedef struct { /// Flag to indicate this process is active RA_gNB_state_t state; - /// DL BWP id of RA process - int dl_bwp_id; - /// UL BWP id of RA process - int ul_bwp_id; /// CORESET0 configured flag int coreset0_configured; /// Slot where preamble was received @@ -199,6 +227,9 @@ typedef struct { rnti_t crnti; /// CFRA flag bool cfra; + // BWP for RA + NR_UE_DL_BWP_t DL_BWP; + NR_UE_UL_BWP_t UL_BWP; } NR_RA_t; /*! \brief gNB common channels */ @@ -346,18 +377,11 @@ typedef struct NR_sched_pucch { * recalculate all S/L, MCS table, or DMRS-related parameters over and over * again. Hence, we store them in this struct for easy reference. */ typedef struct NR_pusch_semi_static_t { - int dci_format; int time_domain_allocation; uint8_t nrOfLayers; uint8_t num_dmrs_cdm_grps_no_data; - int startSymbolIndex; int nrOfSymbols; - - NR_PUSCH_Config_t *pusch_Config; - uint8_t transform_precoding; - uint8_t mcs_table; - long mapping_type; NR_DMRS_UplinkConfig_t *NR_DMRS_UplinkConfig; uint16_t dmrs_config_type; @@ -409,7 +433,6 @@ typedef struct NR_pdsch_semi_static { int startSymbolIndex; int nrOfSymbols; uint8_t nrOfLayers; - uint8_t mcsTableIdx; uint8_t dmrs_ports_id; uint8_t N_PRB_DMRS; uint8_t N_DMRS_SLOT; @@ -440,6 +463,7 @@ typedef struct NR_sched_pdsch { /// only important for retransmissions; otherwise, the TDA in /// NR_pdsch_semi_static_t has precedence int time_domain_allocation; + uint8_t nrOfLayers; } NR_sched_pdsch_t; typedef struct NR_UE_harq { @@ -508,38 +532,6 @@ struct CSI_Report { #define MAX_SR_BITLEN 8 -typedef struct { - uint8_t nb_ssbri_cri; - uint8_t cri_ssbri_bitlen; - uint8_t rsrp_bitlen; - uint8_t diff_rsrp_bitlen; -}L1_RSRP_bitlen_t; - -typedef struct{ - uint8_t ri_restriction; - uint8_t cri_bitlen; - uint8_t ri_bitlen; - uint8_t li_bitlen[8]; - uint8_t pmi_x1_bitlen[8]; - uint8_t pmi_x2_bitlen[8]; - uint8_t cqi_bitlen[8]; -} CSI_Meas_bitlen_t; - -typedef struct nr_csi_report { - NR_CSI_ReportConfig__reportQuantity_PR reportQuantity_type; - long periodicity; - uint16_t offset; - long ** SSB_Index_list; - long ** CSI_Index_list; -// uint8_t nb_of_nzp_csi_report; - uint8_t nb_of_csi_ssb_report; - L1_RSRP_bitlen_t CSI_report_bitlen; - CSI_Meas_bitlen_t csi_meas_bitlen; - int codebook_mode; - int N1; - int N2; -} nr_csi_report_t; - /*! As per the spec 38.212 and table: 6.3.1.1.2-12 in a single UCI sequence we can have multiple CSI_report the number of CSI_report will depend on number of CSI resource sets that are configured in CSI-ResourceConfig RRC IE From spec 38.331 from the IE CSI-ResourceConfig for SSB RSRP reporting we can configure only one resource set @@ -566,11 +558,6 @@ typedef struct NR_UE_ul_harq { /*! \brief scheduling control information set through an API */ #define MAX_CSI_REPORTS 48 typedef struct { - /// the currently active BWP in DL - NR_BWP_Downlink_t *active_bwp; - /// the currently active BWP in UL - NR_BWP_Uplink_t *active_ubwp; - /// the next active BWP ID in DL NR_BWP_Id_t next_dl_bwp_id; /// the next active BWP ID in UL @@ -585,8 +572,6 @@ typedef struct { /// corresponding to the sched_pusch/sched_pdsch structures below int cce_index; uint8_t aggregation_level; - /// maximum aggregation level for UE, can be used to select level - int maxL; /// PUCCH scheduling information. Array of two: HARQ+SR in the first field, /// CSI in second. This order is important for nr_acknack_scheduling()! NR_sched_pucch_t sched_pucch[2]; @@ -673,7 +658,6 @@ typedef struct { } NR_UE_sched_ctrl_t; typedef struct { - boolean_t fiveG_connected; uicc_t *uicc; } NRUEcontext_t; @@ -693,27 +677,34 @@ typedef struct NR_mac_stats { uint32_t pucch0_DTX; int cumul_rsrp; uint8_t num_rsrp_meas; + int8_t srs_wide_band_snr; } NR_mac_stats_t; typedef struct NR_bler_options { double upper; double lower; uint8_t max_mcs; + uint8_t harq_round_max; } NR_bler_options_t; +typedef struct nr_mac_rrc_ul_if_s { + /* TODO add other message types as necessary */ + initial_ul_rrc_message_transfer_func_t initial_ul_rrc_message_transfer; +} nr_mac_rrc_ul_if_t; + /*! \brief UE list used by gNB to order UEs/CC for scheduling*/ -#define MAX_CSI_REPORTCONFIG 48 typedef struct { rnti_t rnti; + uid_t uid; // unique ID of this UE /// scheduling control info nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG]; NR_UE_sched_ctrl_t UE_sched_ctrl; + NR_UE_DL_BWP_t current_DL_BWP; + NR_UE_UL_BWP_t current_UL_BWP; NR_mac_stats_t mac_stats; NR_CellGroupConfig_t *CellGroup; char cg_buf[32768]; /* arbitrary size */ asn_enc_rval_t enc_rval; - /// CCE indexing - int m; // UE selected beam index uint8_t UE_beam_index; bool Msg3_dcch_dtch; @@ -731,6 +722,7 @@ typedef struct { pthread_mutex_t mutex; NR_UE_info_t *list[MAX_MOBILES_PER_GNB+1]; bool sched_csirs; + uid_allocator_t uid_allocator; } NR_UEs_t; #define UE_iterator(BaSe, VaR) NR_UE_info_t ** VaR##pptr=BaSe, *VaR; while ((VaR=*(VaR##pptr++))) @@ -759,12 +751,15 @@ typedef struct gNB_MAC_INST_s { int pusch_target_snrx10; /// Pucch target SNR int pucch_target_snrx10; + /// SNR threshold needed to put or not a PRB in the black list + int ul_prbblack_SNR_threshold; /// PUCCH Failure threshold (compared to consecutive PUCCH DTX) int pucch_failure_thres; /// PUSCH Failure threshold (compared to consecutive PUSCH DTX) int pusch_failure_thres; /// Subcarrier Offset int ssb_SubcarrierOffset; + int ssb_OffsetPointA; /// SIB1 Time domain allocation int sib1_tda; int minRXTXTIMEpdsch; @@ -773,7 +768,7 @@ typedef struct gNB_MAC_INST_s { /// current PDU index (BCH,DLSCH) uint16_t pdu_index[NFAPI_CC_MAX]; int num_ulprbbl; - uint16_t ulprbbl[275]; + uint16_t ulprbbl[MAX_BWP_SIZE]; /// NFAPI Config Request Structure nfapi_nr_config_request_scf_t config[NFAPI_CC_MAX]; /// NFAPI DL Config Request Structure @@ -850,9 +845,10 @@ typedef struct gNB_MAC_INST_s { bool first_MIB; NR_bler_options_t dl_bler; NR_bler_options_t ul_bler; - uint8_t harq_round_max; uint8_t min_grant_prb; uint8_t min_grant_mcs; + + nr_mac_rrc_ul_if_t mac_rrc; } gNB_MAC_INST; #endif /*__LAYER2_NR_MAC_GNB_H__ */ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 108a5dbe91435b6e1265360d2abc5c14df37e097..9adc6ecb5dfc90aa72926d3b233f281814261758 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -139,7 +139,7 @@ extern volatile int oai_exit; pthread_t pdcp_stats_thread_desc; // will be called when 4G F1 implementation will use GTP-U instead of protobuf -boolean_t cu_f1u_data_req( +bool cu_f1u_data_req( protocol_ctxt_t *ctxt_pP, const srb_flag_t srb_flagP, const rb_id_t rb_id, @@ -228,7 +228,7 @@ rlc_op_status_t cu_send_to_du(const protocol_ctxt_t *const ctxt, __func__, rb_id, size); extern instance_t CUuniqInstance; itti_send_msg_to_task(TASK_GTPV1_U, CUuniqInstance, message_p); - return TRUE; + return true; } //----------------------------------------------------------------------------- @@ -239,18 +239,16 @@ rlc_op_status_t cu_send_to_du(const protocol_ctxt_t *const ctxt, * this mem_block_t to be dissected for testing purposes. For further details see test * code at targets/TEST/PDCP/test_pdcp.c:test_pdcp_data_req() */ -boolean_t pdcp_data_req( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *const sourceL2Id, - const uint32_t *const destinationL2Id -) +bool pdcp_data_req(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *const sourceL2Id, + const uint32_t *const destinationL2Id) //----------------------------------------------------------------------------- { pdcp_t *pdcp_p = NULL; @@ -261,7 +259,7 @@ boolean_t pdcp_data_req( uint16_t current_sn = 0; mem_block_t *pdcp_pdu_p = NULL; rlc_op_status_t rlc_status; - boolean_t ret = TRUE; + bool ret = true; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 : 0; @@ -277,7 +275,7 @@ boolean_t pdcp_data_req( if (sdu_buffer_sizeP == 0) { LOG_W(PDCP, "Handed SDU is of size 0! Ignoring...\n"); - return FALSE; + return false; } /* @@ -287,12 +285,12 @@ boolean_t pdcp_data_req( sdu_buffer_sizeP, MAX_IP_PACKET_SIZE); if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) { - AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < NB_RB_MBMS_MAX, return false, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, NB_RB_MBMS_MAX, ctxt_pP->module_id, ctxt_pP->rnti); } else { if (srb_flagP) { - AssertError (rb_idP < 3, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, 3, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < 3, return false, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, 3, ctxt_pP->module_id, ctxt_pP->rnti); } else { - AssertError (rb_idP < LTE_maxDRB, return FALSE, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < LTE_maxDRB, return false, "RB id is too high (%ld/%d) %u %u!\n", rb_idP, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); } } @@ -304,7 +302,7 @@ boolean_t pdcp_data_req( LOG_W(PDCP, PROTOCOL_CTXT_FMT" Instance is not configured for rb_id %ld Ignoring SDU...\n", PROTOCOL_CTXT_ARGS(ctxt_pP), rb_idP); - return FALSE; + return false; } } @@ -371,7 +369,7 @@ boolean_t pdcp_data_req( memset(&pdu_header.mac_i[0],0,PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE); memset(&pdcp_pdu_p->data[sdu_buffer_sizeP + pdcp_header_len],0,PDCP_CONTROL_PLANE_DATA_PDU_MAC_I_SIZE); - if (pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer((unsigned char *)pdcp_pdu_p->data, &pdu_header) == FALSE) { + if (pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer((unsigned char *)pdcp_pdu_p->data, &pdu_header) == false) { LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" Cannot fill PDU buffer with relevant header fields!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p)); @@ -382,7 +380,7 @@ boolean_t pdcp_data_req( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); - return FALSE; + return false; } } else { pdcp_user_plane_data_pdu_header_with_long_sn pdu_header; @@ -390,7 +388,7 @@ boolean_t pdcp_data_req( pdu_header.sn = pdcp_get_next_tx_seq_number(pdcp_p); current_sn = pdu_header.sn ; - if (pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer((unsigned char *)pdcp_pdu_p->data, &pdu_header) == FALSE) { + if (pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer((unsigned char *)pdcp_pdu_p->data, &pdu_header) == false) { LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" Cannot fill PDU buffer with relevant header fields!\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP,pdcp_p)); @@ -401,7 +399,7 @@ boolean_t pdcp_data_req( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); - return FALSE; + return false; } } @@ -422,7 +420,7 @@ boolean_t pdcp_data_req( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); - return FALSE; + return false; } LOG_D(PDCP, "Sequence number %d is assigned to current PDU\n", current_sn); @@ -481,7 +479,7 @@ boolean_t pdcp_data_req( ctxt_pP->module_id, rb_idP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,VCD_FUNCTION_OUT); - return FALSE; + return false; } /* @@ -497,16 +495,16 @@ boolean_t pdcp_data_req( if (ctxt_pP->enb_flag == ENB_FLAG_YES && NODE_IS_DU(RC.rrc[ctxt_pP->module_id]->node_type)) { LOG_E(PDCP, "Can't be DU, bad node type %d \n", RC.rrc[ctxt_pP->module_id]->node_type); - ret=FALSE; + ret = false; } else { rlc_status = pdcp_params.send_rlc_data_req_func(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p,sourceL2Id, destinationL2Id); - ret=FALSE; + ret = false; switch (rlc_status) { case RLC_OP_STATUS_OK: LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); - ret=TRUE; + ret=true; break; case RLC_OP_STATUS_BAD_PARAMETER: @@ -544,7 +542,7 @@ boolean_t pdcp_data_req( itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); //CU_send_DL_RRC_MESSAGE_TRANSFER(ctxt_pP->module_id, message_p); LOG_I(PDCP, "Send F1AP_DL_RRC_MESSAGE with ITTI\n"); - ret=TRUE; + ret=true; } else { rlc_status = rlc_data_req(ctxt_pP , srb_flagP @@ -561,27 +559,27 @@ boolean_t pdcp_data_req( switch (rlc_status) { case RLC_OP_STATUS_OK: LOG_D(PDCP, "Data sending request over RLC succeeded!\n"); - ret=TRUE; + ret=true; break; case RLC_OP_STATUS_BAD_PARAMETER: LOG_W(PDCP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); - ret= FALSE; + ret= false; break; case RLC_OP_STATUS_INTERNAL_ERROR: LOG_W(PDCP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); - ret= FALSE; + ret= false; break; case RLC_OP_STATUS_OUT_OF_RESSOURCES: LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); - ret= FALSE; + ret= false; break; default: LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); - ret= FALSE; + ret= false; break; } // switch case } @@ -596,7 +594,7 @@ boolean_t pdcp_data_req( /* * Control arrives here only if rlc_data_req() returns RLC_OP_STATUS_OK - * so we return TRUE afterwards + * so we return true afterwards */ for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB; pdcp_uid++) { @@ -619,7 +617,7 @@ boolean_t pdcp_data_req( //----------------------------------------------------------------------------- -boolean_t +bool pdcp_data_ind( const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, @@ -638,7 +636,7 @@ pdcp_data_ind( pdcp_sn_t sequence_number = 0; volatile sdu_size_t payload_offset = 0; rb_id_t rb_id = rb_idP; - boolean_t packet_forwarded = FALSE; + bool packet_forwarded = false; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; uint8_t rb_offset= (srb_flagP == 0) ? DTCH -1 :0; @@ -654,7 +652,7 @@ pdcp_data_ind( "[MSG] PDCP UL %s PDU on rb_id %ld\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); if (MBMS_flagP) { - AssertError (rb_idP < NB_RB_MBMS_MAX, return FALSE, + AssertError (rb_idP < NB_RB_MBMS_MAX, return false, "RB id is too high (%ld/%d) %u rnti %x!\n", rb_idP, NB_RB_MBMS_MAX, @@ -680,12 +678,12 @@ pdcp_data_ind( } } else { rb_id = rb_idP % LTE_maxDRB; - AssertError (rb_id < LTE_maxDRB, return FALSE, "RB id is too high (%ld/%d) %u UE %x!\n", + AssertError (rb_id < LTE_maxDRB, return false, "RB id is too high (%ld/%d) %u UE %x!\n", rb_id, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); - AssertError (rb_id > 0, return FALSE, "RB id is too low (%ld/%d) %u UE %x!\n", + AssertError (rb_id > 0, return false, "RB id is too low (%ld/%d) %u UE %x!\n", rb_id, LTE_maxDRB, ctxt_pP->module_id, @@ -700,14 +698,14 @@ pdcp_data_ind( key); free_mem_block(sdu_buffer_pP, __func__); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); - return FALSE; + return false; } } if (sdu_buffer_sizeP == 0) { LOG_W(PDCP, "SDU buffer size is zero! Ignoring this chunk!\n"); - return FALSE; + return false; } if (ctxt_pP->enb_flag) { @@ -764,13 +762,13 @@ pdcp_data_ind( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); - return FALSE; + return false; } #if 0 /* Removed by Cedric */ - if (pdcp_is_rx_seq_number_valid(sequence_number, pdcp_p, srb_flagP) == TRUE) { + if (pdcp_is_rx_seq_number_valid(sequence_number, pdcp_p, srb_flagP) == true) { LOG_T(PDCP, "Incoming PDU has a sequence number (%d) in accordance with RX window\n", sequence_number); /* if (dc == PDCP_DATA_PDU ) LOG_D(PDCP, "Passing piggybacked SDU to NAS driver...\n"); @@ -788,7 +786,7 @@ pdcp_data_ind( */ LOG_W(PDCP, "Ignoring PDU...\n"); free_mem_block(sdu_buffer_pP, __func__); - return FALSE; + return false; } #endif @@ -837,7 +835,7 @@ pdcp_data_ind( LOG_W(PDCP, "Ignoring PDU...\n"); free_mem_block(sdu_buffer_pP, __func__); /* TODO: indicate integrity verification failure to upper layer */ - return FALSE; + return false; } if (sequence_number < pdcp_p->next_pdcp_rx_sn) @@ -864,7 +862,7 @@ pdcp_data_ind( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); - return TRUE; + return true; } /* if (srb_flagP) */ /* @@ -892,7 +890,7 @@ pdcp_data_ind( LOG_W(PDCP, "Ignoring PDU...\n"); free_mem_block(sdu_buffer_pP, __func__); /* TODO: indicate integrity verification failure to upper layer */ - return FALSE; + return false; } else if (pdcp_p->next_pdcp_rx_sn - sequence_number > reordering_window) { pdcp_p->rx_hfn++; rx_hfn_for_count = pdcp_p->rx_hfn; @@ -948,7 +946,7 @@ pdcp_data_ind( LOG_W(PDCP, "Ignoring PDU...\n"); free_mem_block(sdu_buffer_pP, __func__); /* TODO: indicate integrity verification failure to upper layer */ - return FALSE; + return false; } /* TODO: specs say we have to store this PDU in a list and then deliver @@ -1015,7 +1013,7 @@ pdcp_data_ind( LOG_W(PDCP, "Ignoring PDU...\n"); free_mem_block(sdu_buffer_pP, __func__); /* TODO: indicate integrity verification failure to upper layer */ - return FALSE; + return false; } break; @@ -1039,7 +1037,7 @@ pdcp_data_ind( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); - return TRUE; + return true; } // XXX Decompression would be done at this point @@ -1051,7 +1049,7 @@ pdcp_data_ind( */ if (LINK_ENB_PDCP_TO_GTPV1U) { - if ((TRUE == ctxt_pP->enb_flag) && (FALSE == srb_flagP)) { + if ((true == ctxt_pP->enb_flag) && (false == srb_flagP)) { LOG_D(PDCP, "Sending packet to GTP, Calling GTPV1U_ENB_TUNNEL_DATA_REQ ue %x rab %ld len %u\n", ctxt_pP->rnti, rb_id + 4, @@ -1069,10 +1067,10 @@ pdcp_data_ind( GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ctxt_pP->rnti; GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); - packet_forwarded = TRUE; + packet_forwarded = true; } } else { - packet_forwarded = FALSE; + packet_forwarded = false; } #ifdef MBMS_MULTICAST_OUT @@ -1086,13 +1084,13 @@ pdcp_data_ind( // dest_addr.sin_addr.s_addr = ip_header->daddr; // sendto(mbms_socket, &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset, MSG_DONTWAIT, (struct sockaddr*)&dest_addr, sizeof(dest_addr)); - // //packet_forwarded = TRUE; + // //packet_forwarded = true; } #endif - if (FALSE == packet_forwarded) { + if (false == packet_forwarded) { notifiedFIFO_elt_t * new_sdu_p = newNotifiedFIFO_elt(sdu_buffer_sizeP - payload_offset + sizeof (pdcp_data_ind_header_t), 0, NULL, NULL); if ((MBMS_flagP == 0) && (pdcp_p->rlc_mode == RLC_MODE_AM)) { @@ -1185,7 +1183,7 @@ pdcp_data_ind( } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,VCD_FUNCTION_OUT); - return TRUE; + return true; } void pdcp_update_stats(const protocol_ctxt_t *const ctxt_pP) { @@ -1297,7 +1295,7 @@ pdcp_run ( NULL, NULL ); - if (result != TRUE) + if (result != true) LOG_E(PDCP, "PDCP data request failed!\n"); // Message buffer has been processed, free it now. @@ -1420,7 +1418,7 @@ pdcp_mbms_run ( // NULL, NULL // ); // -// if (result != TRUE) +// if (result != true) // LOG_E(PDCP, "PDCP data request failed!\n"); // // // Message buffer has been processed, free it now. @@ -1549,10 +1547,7 @@ void pdcp_add_UE(const protocol_ctxt_t *const ctxt_pP) { } //----------------------------------------------------------------------------- -boolean_t -pdcp_remove_UE( - const protocol_ctxt_t *const ctxt_pP -) +bool pdcp_remove_UE(const protocol_ctxt_t *const ctxt_pP) //----------------------------------------------------------------------------- { LTE_DRB_Identity_t srb_id = 0; @@ -1599,19 +1594,17 @@ pdcp_remove_UE( //----------------------------------------------------------------------------- -boolean_t -rrc_pdcp_config_asn1_req ( - const protocol_ctxt_t *const ctxt_pP, - LTE_SRB_ToAddModList_t *const srb2add_list_pP, - LTE_DRB_ToAddModList_t *const drb2add_list_pP, - LTE_DRB_ToReleaseList_t *const drb2release_list_pP, - const uint8_t security_modeP, - uint8_t *const kRRCenc_pP, - uint8_t *const kRRCint_pP, - uint8_t *const kUPenc_pP, - LTE_PMCH_InfoList_r9_t *const pmch_InfoList_r9_pP, - rb_id_t *const defaultDRB -) +bool +rrc_pdcp_config_asn1_req(const protocol_ctxt_t *const ctxt_pP, + LTE_SRB_ToAddModList_t *const srb2add_list_pP, + LTE_DRB_ToAddModList_t *const drb2add_list_pP, + LTE_DRB_ToReleaseList_t *const drb2release_list_pP, + const uint8_t security_modeP, + uint8_t *const kRRCenc_pP, + uint8_t *const kRRCint_pP, + uint8_t *const kUPenc_pP, + LTE_PMCH_InfoList_r9_t *const pmch_InfoList_r9_pP, + rb_id_t *const defaultDRB) //----------------------------------------------------------------------------- { long int lc_id = 0; @@ -1669,7 +1662,7 @@ rrc_pdcp_config_asn1_req ( PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), key); free(pdcp_p); - return TRUE; + return true; } else { LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD key 0x%"PRIx64"\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), @@ -1784,13 +1777,13 @@ rrc_pdcp_config_asn1_req ( PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), key_defaultDRB); free(pdcp_p); - return TRUE; + return true; } else if (h_rc != HASH_TABLE_OK) { LOG_E(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD ADD key 0x%"PRIx64" FAILED\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), key); free(pdcp_p); - return TRUE; + return true; } else { LOG_D(PDCP, PROTOCOL_PDCP_CTXT_FMT" CONFIG_ACTION_ADD ADD key 0x%"PRIx64"\n", PROTOCOL_PDCP_CTXT_ARGS(ctxt_pP, pdcp_p), @@ -1944,7 +1937,7 @@ rrc_pdcp_config_asn1_req ( if (ctxt_pP->enb_flag) { drb_id = (mch_id * LTE_maxSessionPerPMCH ) + lc_id ;//+ (LTE_maxDRB + 3)*MAX_MOBILES_PER_ENB; // 1 - if (pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_id][lc_id].instanciated_instance == TRUE) { + if (pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_id][lc_id].instanciated_instance == true) { action = CONFIG_ACTION_MBMS_MODIFY; } else { action = CONFIG_ACTION_MBMS_ADD; @@ -1952,7 +1945,7 @@ rrc_pdcp_config_asn1_req ( } else { drb_id = (mch_id * LTE_maxSessionPerPMCH ) + lc_id; // + (LTE_maxDRB + 3); // 15 - if (pdcp_mbms_array_ue[ctxt_pP->module_id][mch_id][lc_id].instanciated_instance == TRUE) { + if (pdcp_mbms_array_ue[ctxt_pP->module_id][mch_id][lc_id].instanciated_instance == true) { action = CONFIG_ACTION_MBMS_MODIFY; } else { action = CONFIG_ACTION_MBMS_ADD; @@ -1990,23 +1983,22 @@ rrc_pdcp_config_asn1_req ( } //----------------------------------------------------------------------------- -boolean_t -pdcp_config_req_asn1 ( - const protocol_ctxt_t *const ctxt_pP, - pdcp_t *const pdcp_pP, - const srb_flag_t srb_flagP, - const rlc_mode_t rlc_modeP, - const config_action_t actionP, - const uint16_t lc_idP, - const uint16_t mch_idP, - const rb_id_t rb_idP, - const uint8_t rb_snP, - const uint8_t rb_reportP, - const uint16_t header_compression_profileP, - const uint8_t security_modeP, - uint8_t *const kRRCenc_pP, - uint8_t *const kRRCint_pP, - uint8_t *const kUPenc_pP) +bool +pdcp_config_req_asn1(const protocol_ctxt_t *const ctxt_pP, + pdcp_t *const pdcp_pP, + const srb_flag_t srb_flagP, + const rlc_mode_t rlc_modeP, + const config_action_t actionP, + const uint16_t lc_idP, + const uint16_t mch_idP, + const rb_id_t rb_idP, + const uint8_t rb_snP, + const uint8_t rb_reportP, + const uint16_t header_compression_profileP, + const uint8_t security_modeP, + uint8_t *const kRRCenc_pP, + uint8_t *const kRRCint_pP, + uint8_t *const kUPenc_pP) //----------------------------------------------------------------------------- { @@ -2015,7 +2007,7 @@ pdcp_config_req_asn1 ( DevAssert(pdcp_pP != NULL); if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - pdcp_pP->is_ue = FALSE; + pdcp_pP->is_ue = false; pdcp_add_UE(ctxt_pP); //pdcp_eNB_UE_instance_to_rnti[ctxtP->module_id] = ctxt_pP->rnti; @@ -2035,11 +2027,11 @@ pdcp_config_req_asn1 ( //pdcp_eNB_UE_instance_to_rnti_index = (pdcp_eNB_UE_instance_to_rnti_index + 1) % MAX_MOBILES_PER_ENB; } else { - pdcp_pP->is_ue = TRUE; + pdcp_pP->is_ue = true; pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; } - pdcp_pP->is_srb = (srb_flagP == SRB_FLAG_YES) ? TRUE : FALSE; + pdcp_pP->is_srb = srb_flagP == SRB_FLAG_YES; pdcp_pP->lcid = lc_idP; pdcp_pP->rb_id = rb_idP; pdcp_pP->header_compression_profile = header_compression_profileP; @@ -2162,10 +2154,10 @@ pdcp_config_req_asn1 ( rb_idP); if (ctxt_pP->enb_flag == ENB_FLAG_YES) { - pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = TRUE ; + pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = true ; pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_idP][lc_idP].rb_id = rb_idP; } else { - pdcp_mbms_array_ue[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = TRUE ; + pdcp_mbms_array_ue[ctxt_pP->module_id][mch_idP][lc_idP].instanciated_instance = true ; pdcp_mbms_array_ue[ctxt_pP->module_id][mch_idP][lc_idP].rb_id = rb_idP; } @@ -2245,10 +2237,10 @@ void rrc_pdcp_config_req ( pdcp_p->rb_id = rb_idP; if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - pdcp_p->is_ue = TRUE; + pdcp_p->is_ue = true; pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; } else { - pdcp_p->is_ue = FALSE; + pdcp_p->is_ue = false; } pdcp_p->next_pdcp_tx_sn = 0; @@ -2321,10 +2313,10 @@ void rrc_pdcp_config_req ( pdcp_p->rb_id = rb_idP; if (ctxt_pP->enb_flag == ENB_FLAG_NO) { - pdcp_p->is_ue = TRUE; + pdcp_p->is_ue = true; pdcp_UE_UE_module_id_to_rnti[ctxt_pP->module_id] = ctxt_pP->rnti; } else { - pdcp_p->is_ue = FALSE; + pdcp_p->is_ue = false; } pdcp_p->next_pdcp_tx_sn = 0; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 332ee382d712bd3c161623845d9a08d1d002569a..8cbc49d756356f697428e536843539b1b9bf72d2 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -51,7 +51,7 @@ typedef rlc_op_status_t (*send_rlc_data_req_func_t)(const protocol_ctxt_t *cons const rb_id_t, const mui_t, confirm_t, sdu_size_t, mem_block_t *,const uint32_t *const, const uint32_t *const); -typedef boolean_t (pdcp_data_ind_t)( const protocol_ctxt_t *, const srb_flag_t, +typedef bool (pdcp_data_ind_t)( const protocol_ctxt_t *, const srb_flag_t, const MBMS_flag_t, const rb_id_t, const sdu_size_t, mem_block_t *,const uint32_t *const, const uint32_t *const); typedef pdcp_data_ind_t* pdcp_data_ind_func_t; @@ -153,14 +153,13 @@ typedef struct pdcp_stats_s { typedef struct pdcp_s { - //boolean_t instanciated_instance; uint16_t header_compression_profile; /* SR: added this flag to distinguish UE/eNB instance as pdcp_run for virtual * mode can receive data on NETLINK for eNB while eNB_flag = 0 and for UE when eNB_flag = 1 */ - boolean_t is_ue; - boolean_t is_srb; + bool is_ue; + bool is_srb; /* Configured security algorithms */ uint8_t cipheringAlgorithm; @@ -217,7 +216,7 @@ typedef struct pdcp_s { } pdcp_t; typedef struct pdcp_mbms_s { - boolean_t instanciated_instance; + bool instanciated_instance; rb_id_t rb_id; } pdcp_mbms_t; @@ -230,7 +229,7 @@ typedef struct pdcp_mbms_s { * under targets/TEST/PDCP/ */ -/*! \fn boolean_t pdcp_data_req(const protocol_ctxt_t* const , srb_flag_t , rb_id_t , mui_t , confirm_t ,sdu_size_t , unsigned char* , pdcp_transmission_mode_t ) +/*! \fn bool pdcp_data_req(const protocol_ctxt_t* const , srb_flag_t , rb_id_t , mui_t , confirm_t ,sdu_size_t , unsigned char* , pdcp_transmission_mode_t ) * \brief This functions handles data transfer requests coming either from RRC or from IP * \param[in] ctxt_pP Running context. * \param[in] rab_id Radio Bearer ID @@ -239,38 +238,34 @@ typedef struct pdcp_mbms_s { * \param[in] sdu_buffer_size Size of incoming SDU in bytes * \param[in] sdu_buffer Buffer carrying SDU * \param[in] mode flag to indicate whether the userplane data belong to the control plane or data plane or transparent -* \return TRUE on success, FALSE otherwise +* \return true on success, false otherwise * \note None * @ingroup _pdcp */ -boolean_t pdcp_data_req( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t mode, - const uint32_t * sourceL2Id, - const uint32_t * destinationL2Id -); - -boolean_t cu_f1u_data_req( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t mode, - const uint32_t *const sourceL2Id, - const uint32_t *const destinationL2Id - ); - -/*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t) +bool pdcp_data_req(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode, + const uint32_t * sourceL2Id, + const uint32_t * destinationL2Id); + +bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode, + const uint32_t *const sourceL2Id, + const uint32_t *const destinationL2Id); + +/*! \fn bool pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, bool) * \brief This functions handles data transfer indications coming from RLC * \param[in] ctxt_pP Running context. * \param[in] Shows if rb is SRB @@ -279,7 +274,7 @@ boolean_t cu_f1u_data_req( * \param[in] sdu_buffer_size Size of incoming SDU in bytes * \param[in] sdu_buffer Buffer carrying SDU * \param[in] is_data_plane flag to indicate whether the userplane data belong to the control plane or data plane -* \return TRUE on success, FALSE otherwise +* \return TRUE on success, false otherwise * \note None * @ingroup _pdcp */ @@ -316,20 +311,18 @@ void rrc_pdcp_config_req ( * \param[in] defaultDRB Default DRB ID * \return A status about the processing, OK or error code. */ -boolean_t rrc_pdcp_config_asn1_req ( - const protocol_ctxt_t *const ctxt_pP, - LTE_SRB_ToAddModList_t *const srb2add_list, - LTE_DRB_ToAddModList_t *const drb2add_list, - LTE_DRB_ToReleaseList_t *const drb2release_list, - const uint8_t security_modeP, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc, - LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9, - rb_id_t *const defaultDRB -); - -/*! \fn boolean_t pdcp_config_req_asn1 (const protocol_ctxt_t* const ctxt_pP, srb_flag_t srb_flagP, uint32_t action, rb_id_t rb_id, uint8_t rb_sn, uint8_t rb_report, uint16_t header_compression_profile, uint8_t security_mode) +bool rrc_pdcp_config_asn1_req(const protocol_ctxt_t *const ctxt_pP, + LTE_SRB_ToAddModList_t *const srb2add_list, + LTE_DRB_ToAddModList_t *const drb2add_list, + LTE_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc, + LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9, + rb_id_t *const defaultDRB); + +/*! \fn bool pdcp_config_req_asn1 (const protocol_ctxt_t* const ctxt_pP, srb_flag_t srb_flagP, uint32_t action, rb_id_t rb_id, uint8_t rb_sn, uint8_t rb_report, uint16_t header_compression_profile, uint8_t security_mode) * \brief Function for RRC to configure a Radio Bearer. * \param[in] ctxt_pP Running context. * \param[in] pdcp_pP Pointer on PDCP structure. @@ -349,22 +342,21 @@ boolean_t rrc_pdcp_config_asn1_req ( * \param[in] kUPenc User-Plane encryption key * \return A status about the processing, OK or error code. */ -boolean_t pdcp_config_req_asn1 ( - const protocol_ctxt_t *const ctxt_pP, - pdcp_t *const pdcp_pP, - const srb_flag_t srb_flagP, - const rlc_mode_t rlc_mode, - const uint32_t action, - const uint16_t lc_id, - const uint16_t mch_id, - const rb_id_t rb_id, - const uint8_t rb_sn, - const uint8_t rb_report, - const uint16_t header_compression_profile, - const uint8_t security_mode, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc); +bool pdcp_config_req_asn1(const protocol_ctxt_t *const ctxt_pP, + pdcp_t *const pdcp_pP, + const srb_flag_t srb_flagP, + const rlc_mode_t rlc_mode, + const uint32_t action, + const uint16_t lc_id, + const uint16_t mch_id, + const rb_id_t rb_id, + const uint8_t rb_sn, + const uint8_t rb_report, + const uint16_t header_compression_profile, + const uint8_t security_mode, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc); /*! \fn void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP) * \brief Function (for RRC) to add a new UE in PDCP module @@ -373,13 +365,12 @@ boolean_t pdcp_config_req_asn1 ( */ void pdcp_add_UE(const protocol_ctxt_t *const ctxt_pP); -/*! \fn boolean_t pdcp_remove_UE(const protocol_ctxt_t* const ctxt_pP) +/*! \fn bool pdcp_remove_UE(const protocol_ctxt_t* const ctxt_pP) * \brief Function for RRC to remove UE from PDCP module hashtable * \param[in] ctxt_pP Running context. * \return A status about the processing, OK or error code. */ -boolean_t pdcp_remove_UE( - const protocol_ctxt_t *const ctxt_pP); +bool pdcp_remove_UE(const protocol_ctxt_t *const ctxt_pP); /*! \fn void rrc_pdcp_config_release( const protocol_ctxt_t* const, rb_id_t) * \brief This functions is unused diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.c index ef674132c45f38d9e38ed4c564559e4edee85237..77d3cf3857a3d32f2616ea8ae95709ac4e308f6d 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.c @@ -32,7 +32,7 @@ #include "pdcp.h" #include "pdcp_primitives.h" -extern boolean_t util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index); +extern bool util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index); /* * Parses data/control field out of buffer of User Plane PDCP Data PDU with @@ -123,13 +123,13 @@ uint8_t pdcp_get_sequence_number_of_pdu_with_SRB_sn(unsigned char* pdu_buffer) * Fills the incoming buffer with the fields of the header for srb sn * * @param pdu_buffer PDCP PDU buffer - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char* pdu_buffer, \ - pdcp_control_plane_data_pdu_header* pdu) +bool pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char* pdu_buffer, + pdcp_control_plane_data_pdu_header* pdu) { if (pdu_buffer == NULL || pdu == NULL) { - return FALSE; + return false; } /* @@ -138,20 +138,20 @@ boolean_t pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char uint8_t sequence_number = pdu->sn; pdu_buffer[0] = sequence_number & 0x1F; // 5bit sn - return TRUE; + return true; } /* * Fills the incoming buffer with the fields of the header for long sn * * @param pdu_buffer PDCP PDU buffer - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer, \ - pdcp_user_plane_data_pdu_header_with_long_sn* pdu) +bool pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer, + pdcp_user_plane_data_pdu_header_with_long_sn* pdu) { if (pdu_buffer == NULL || pdu == NULL) { - return FALSE; + return false; } /* @@ -170,7 +170,7 @@ boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer[0] |= 0x80; // set the first bit as 1 } - return TRUE; + return true; } /* @@ -178,13 +178,14 @@ boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* * * @param pdu_buffer The buffer that PDU will be serialized into * @param pdu A status report header - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_buffer, \ - uint8_t bitmap[512], pdcp_control_pdu_for_pdcp_status_report* pdu) +bool pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_buffer, + uint8_t bitmap[512], + pdcp_control_pdu_for_pdcp_status_report* pdu) { if (pdu_buffer == NULL || pdu == NULL) { - return FALSE; + return false; } /* @@ -205,6 +206,6 @@ boolean_t pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_b */ memcpy(pdu_buffer + 2, bitmap, 512); - return TRUE; + return true; } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h index 8b5ebe7287c52ddbb15409edceec218569127b0d..423f69afc9cdfb47041c5b19852244fd75391a18 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_primitives.h @@ -142,18 +142,18 @@ uint8_t pdcp_get_sequence_number_of_pdu_with_SRB_sn(unsigned char* pdu_buffer); * Fills the incoming buffer with the fields of the header for SRB1 * * @param pdu_buffer PDCP PDU buffer - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char* pdu_buffer, \ - pdcp_control_plane_data_pdu_header* pdu); +bool pdcp_serialize_control_plane_data_pdu_with_SRB_sn_buffer(unsigned char* pdu_buffer, + pdcp_control_plane_data_pdu_header* pdu); /* * Fills the incoming buffer with the fields of the header for long SN (RLC UM and AM) * * @param pdu_buffer PDCP PDU buffer - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer, \ - pdcp_user_plane_data_pdu_header_with_long_sn* pdu); +bool pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* pdu_buffer, + pdcp_user_plane_data_pdu_header_with_long_sn* pdu); /* * Fills the incoming status report header with given value of bitmap @@ -162,10 +162,11 @@ boolean_t pdcp_serialize_user_plane_data_pdu_with_long_sn_buffer(unsigned char* * @param FMS First Missing PDCP SN * @param bitmap Received/Missing sequence number bitmap * @param pdu A status report header - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_buffer, \ - uint8_t bitmap[512], pdcp_control_pdu_for_pdcp_status_report* pdu); +bool pdcp_serialize_control_pdu_for_pdcp_status_report(unsigned char* pdu_buffer, + uint8_t bitmap[512], + pdcp_control_pdu_for_pdcp_status_report* pdu); int pdcp_netlink_dequeue_element(const protocol_ctxt_t* const ctxt_pP, struct pdcp_netlink_element_s **data_ppP); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c index cdc583ef217873df5f794f6f9359136d1c2a1a33..31beb3a9e0663dff64ba6f2c3b0750b3b93217bf 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.c @@ -33,12 +33,12 @@ /* * Initializes sequence numbering state * @param pdcp_entity The PDCP entity to be initialized - * @return boolean_t TRUE on success, FALSE otherwise + * @return bool true on success, false otherwise */ -boolean_t pdcp_init_seq_numbers(pdcp_t* pdcp_entity) +bool pdcp_init_seq_numbers(pdcp_t* pdcp_entity) { if (pdcp_entity == NULL) { - return FALSE; + return false; } /* Sequence number state variables */ @@ -55,34 +55,34 @@ boolean_t pdcp_init_seq_numbers(pdcp_t* pdcp_entity) // Shall UE and eNB behave differently on initialization? (see 7.1.e) pdcp_entity->last_submitted_pdcp_rx_sn = 4095; - return TRUE; + return true; } -boolean_t pdcp_is_seq_num_size_valid(pdcp_t* pdcp_entity) +bool pdcp_is_seq_num_size_valid(pdcp_t* pdcp_entity) { if (pdcp_entity == NULL) { - return FALSE; + return false; } // Check if the size of SN is valid (see 3GPP TS 36.323 v10.1.0 item 6.3.2) if (pdcp_entity->seq_num_size != 5 && pdcp_entity->seq_num_size != 7 && pdcp_entity->seq_num_size != 12) { LOG_W(PDCP, "Incoming SN size is invalid! (Expected: {5 | 7 | 12}, Received: %d\n", pdcp_entity->seq_num_size); - return FALSE; + return false; } - return TRUE; + return true; } /** * Check if SN number is in the range according to SN size */ -boolean_t pdcp_is_seq_num_valid(uint16_t seq_num, uint8_t seq_num_size) +bool pdcp_is_seq_num_valid(uint16_t seq_num, uint8_t seq_num_size) { if (seq_num >= 0 && seq_num <= pdcp_calculate_max_seq_num_for_given_size(seq_num_size)) { - return TRUE; + return true; } - return FALSE; + return false; } uint16_t pdcp_calculate_max_seq_num_for_given_size(uint8_t seq_num_size) @@ -96,7 +96,7 @@ uint16_t pdcp_calculate_max_seq_num_for_given_size(uint8_t seq_num_size) uint16_t pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity) { - if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE) { + if (pdcp_is_seq_num_size_valid(pdcp_entity) == false) { return -1; } @@ -118,10 +118,10 @@ uint16_t pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity) return pdcp_seq_num; } -boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity) +bool pdcp_advance_rx_window(pdcp_t* pdcp_entity) { - if (pdcp_is_seq_num_size_valid(pdcp_entity) == FALSE) { - return FALSE; + if (pdcp_is_seq_num_size_valid(pdcp_entity) == false) { + return false; } /* @@ -137,10 +137,10 @@ boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity) pdcp_entity->next_pdcp_rx_sn++; } - return TRUE; + return true; } -boolean_t pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entity) +bool pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entity) { /* * Incoming sequence number and PDCP entity were already @@ -158,5 +158,5 @@ boolean_t pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entit LOG_D(PDCP, "Marking %d. bit of %d. octet of status bitmap\n", (seq_num % 8) + 1, octet_index); util_mark_nth_bit_of_octet(&pdcp_entity->missing_pdu_bitmap[octet_index], seq_num % 8); util_print_binary_representation((uint8_t*)"Current state of relevant octet: ", pdcp_entity->missing_pdu_bitmap[octet_index]); - return TRUE; + return true; } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h index 172c9810e69c29ad81f911f6b61a72759cf9812e..bff98d1b00ed84b1356e69ad4e1cd55abb50acaf 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_sequence_manager.h @@ -35,17 +35,17 @@ * @param pdcp_entity The PDCP entity to be initialized * @return none */ -boolean_t pdcp_init_seq_numbers(pdcp_t* pdcp_entity); +bool pdcp_init_seq_numbers(pdcp_t* pdcp_entity); /** * Checks if incoming PDCP entitiy pointer and relevant sequence number size is valid - * @return TRUE (0x01) if it is valid, FALSE (0x00) otherwise + * @return true (0x01) if it is valid, false (0x00) otherwise */ -boolean_t pdcp_is_seq_num_size_valid(pdcp_t* pdcp_entity); +bool pdcp_is_seq_num_size_valid(pdcp_t* pdcp_entity); /** * Check if SN number is in the range according to SN size - * @return TRUE if it is valid, FALSE otherwise + * @return true if it is valid, false otherwise */ -boolean_t pdcp_is_seq_num_valid(uint16_t seq_num, uint8_t seq_num_size); +bool pdcp_is_seq_num_valid(uint16_t seq_num, uint8_t seq_num_size); /** * Returns the maximum allowed sequence number value for given size of SN field * @return Max sequence number value @@ -58,11 +58,11 @@ uint16_t pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity); /** * Advances the RX window state of given PDCP entity upon successfull receipt of a SDU */ -boolean_t pdcp_advance_rx_window(pdcp_t* pdcp_entity); +bool pdcp_advance_rx_window(pdcp_t* pdcp_entity); /** * Updates missing PDU bitmap with incoming sequence number -* @return TRUE if successful, FALSE otherwise +* @return true if successful, false otherwise */ -boolean_t pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entity); +bool pdcp_mark_current_pdu_as_received(uint16_t seq_num, pdcp_t* pdcp_entity); #endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c index cf8218829fe605a51f47365c513a8832011fa635..79f6d688203620ee25802dd8e4471f6aaea85472 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.c @@ -130,9 +130,9 @@ void util_print_binary_representation(unsigned char* message, uint8_t octet) * * @param octet 8-bit data * @param index Index of bit to be set - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index) +bool util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index) { uint8_t mask = 0x80; @@ -148,6 +148,6 @@ boolean_t util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index) */ *octet |= mask; - return TRUE; + return true; } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.h index 49846c7a9fbd75bfbefb64f1d32af56cb958e262..89b8ff672f7824867fae61dcfdc8cf24ca1d81a6 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_util.h @@ -66,8 +66,8 @@ void util_print_binary_representation(unsigned char* message, uint8_t octet); * * @param octet Octet * @param index Index - * @return TRUE on success, FALSE otherwise + * @return true on success, false otherwise */ -boolean_t util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index); +bool util_mark_nth_bit_of_octet(uint8_t* octet, uint8_t index); #endif // PDCP_UTIL_H diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index 4eb0907046aef6ef7301878a26b24df22ec2a83a..ddc7bf85e851f14fac0bdcac0c8279d0c391870d 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -52,7 +52,7 @@ rlc_am_get_status_pdu_buffer_occupancy( rlc_sn_t sn_cursor = rlc_pP->vr_r; rlc_sn_t sn_prev = rlc_pP->vr_r; rlc_sn_t sn_end = rlc_pP->vr_ms; - boolean_t segment_loop_end = false; + bool segment_loop_end = false; if (sn_prev != sn_end) { while ((RLC_AM_DIFF_SN(sn_prev,rlc_pP->vr_r) < RLC_AM_DIFF_SN(sn_end,rlc_pP->vr_r)) && (cursor_p != NULL)) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h index 1b6d8375655d00a98b5851daf8e40cc4c207535f..95c47943a49abcfc0501aa0e306178e4cbd1538c 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_entity.h @@ -54,7 +54,7 @@ typedef struct rlc_am_entity_s { rb_id_t rb_id; /*!< \brief Radio bearer identifier, for statistics and trace purpose. */ logical_chan_id_t channel_id; /*!< \brief Transport channel identifier. */ - boolean_t is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ + bool is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ rlc_buffer_occupancy_t sdu_buffer_occupancy; /*!< \brief Number of bytes of unsegmented SDUs. */ rlc_buffer_occupancy_t status_buffer_occupancy; /*!< \brief Number of bytes of control PDUs waiting for transmission. */ @@ -76,7 +76,7 @@ typedef struct rlc_am_entity_s { rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer; /*!< \brief Transmission PDU data buffer. Used also for retransmissions */ signed int retrans_num_pdus; /*!< \brief Number of PDUs in the retransmission buffer. */ signed int retrans_num_bytes_to_retransmit; /*!< \brief Number of bytes in the retransmission buffer to be retransmitted. Only payload is taken into account */ - boolean_t force_poll; /*!< \brief force poll due to t_poll_retransmit time-out. */ + bool force_poll; /*!< \brief force poll due to t_poll_retransmit time-out. */ //--------------------------------------------------------------------- // RX BUFFERS @@ -186,8 +186,8 @@ typedef struct rlc_am_entity_s { // note occupancy of other buffers is deducted from nb elements in lists rlc_buffer_occupancy_t buffer_occupancy_retransmission_buffer; /*!< \brief Number of PDUs. */ - boolean_t initialized; /*!< \brief Boolean for rlc_am_entity_t struct initialization. */ - boolean_t configured; /*!< \brief Boolean for rlc_am_entity_t struct configuration. */ + bool initialized; /*!< \brief Boolean for rlc_am_entity_t struct initialization. */ + bool configured; /*!< \brief Boolean for rlc_am_entity_t struct configuration. */ } rlc_am_entity_t; /** @} */ # endif diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c index cb09f24855aa789cffdea78b3d4851a08e54f901..8ff29fa44bfe944e1c859ec79e04a0fb5bcec5e5 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_init.c @@ -32,7 +32,7 @@ rlc_am_init( const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlc_pP) { - if (rlc_pP->initialized == TRUE) { + if (rlc_pP->initialized == true) { LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[AM INIT] INITIALIZATION ALREADY DONE, DOING NOTHING\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); } else { @@ -79,7 +79,7 @@ rlc_am_init( rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1 - rlc_pP->initialized = TRUE; + rlc_pP->initialized = true; } } //----------------------------------------------------------------------------- @@ -134,7 +134,7 @@ rlc_am_reestablish( rlc_pP->last_absolute_subframe_status_indication = 0xFFFFFFFF; // any value > 1 - rlc_pP->initialized = TRUE; + rlc_pP->initialized = true; } @@ -197,7 +197,7 @@ rlc_am_configure( const uint32_t t_reorderingP, const uint32_t t_status_prohibitP) { - if (rlc_pP->configured == TRUE) { + if (rlc_pP->configured == true) { LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[RECONFIGURE] max_retx_threshold %d poll_pdu %d poll_byte %d t_poll_retransmit %d t_reordering %d t_status_prohibit %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), max_retx_thresholdP, @@ -235,7 +235,7 @@ rlc_am_configure( rlc_am_init_timer_reordering (ctxt_pP, rlc_pP, t_reorderingP); rlc_am_init_timer_status_prohibit(ctxt_pP, rlc_pP, t_status_prohibitP); - rlc_pP->configured = TRUE; + rlc_pP->configured = true; } } diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c index 0957c20bdfc2ba6ae64811edbfcf11fdd3369285..a5f0b4f9ef096ecd1b1a8e78da076dc3141d23d3 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.c @@ -183,12 +183,10 @@ rlc_am_send_sdu ( } } //----------------------------------------------------------------------------- -void -rlc_am_reassemble_pdu( - const protocol_ctxt_t *const ctxt_pP, - rlc_am_entity_t *const rlc_pP, - mem_block_t *const tb_pP, - boolean_t free_rlc_pdu) { +void rlc_am_reassemble_pdu(const protocol_ctxt_t *const ctxt_pP, + rlc_am_entity_t *const rlc_pP, + mem_block_t *const tb_pP, + bool free_rlc_pdu) { int i,j; rlc_am_pdu_info_t *pdu_info = &((rlc_am_rx_pdu_management_t *)(tb_pP->data))->pdu_info; LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[REASSEMBLY PDU] TRY REASSEMBLY PDU SN=%03d\n", diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h index bf9bd58fb52887b4b2f1cfdd08b2c1fe44bce3a3..839e7d9304fbce3cb2371017018b19f9921e97c7 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_reassembly.h @@ -57,14 +57,14 @@ void rlc_am_reassembly (const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * */ void rlc_am_send_sdu (const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP); -/*! \fn void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, const mem_block_t* const tb_pP,boolean_t free_rlc_pdu) +/*! \fn void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, const mem_block_t* const tb_pP, bool free_rlc_pdu) * \brief Reassembly a RLC AM PDU, depending of the content of this PDU, data will be reassemblied to the current output SDU, the current will be sent to higher layers or not, after or before the reassembly, or no send of SDU will be triggered, depending on FI field in PDU header. * \param[in] ctxtP Running context. * \param[in] rlc_pP RLC AM protocol instance pointer. * \param[in] tb_pP RLC AM PDU embedded in a mem_block_t. * \param[in] free_rlc_pdu Flag for freeing RLC AM PDU after reassembly. */ -void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, mem_block_t* const tb_pP,boolean_t free_rlc_pdu); +void rlc_am_reassemble_pdu(const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP, mem_block_t* const tb_pP, bool free_rlc_pdu); /** @} */ #endif diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c index 916d1513b0f1f1f0c65ddac2c9bc64a89eb81169..a749aa035e1e161e2cc76b998a126b225cec9289 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_receiver.c @@ -328,7 +328,7 @@ rlc_am_receive_process_data_pdu ( rlc_am_pdu_info_t* pdu_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; rlc_am_pdu_sn_10_t* rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t*)first_byte_pP; rlc_am_rx_pdu_status_t pdu_status = RLC_AM_DATA_PDU_STATUS_OK; - boolean_t reassemble = false; + bool reassemble = false; if (rlc_am_get_data_pdu_infos(ctxt_pP,rlc_pP, rlc_am_pdu_sn_10_p, tb_size_in_bytesP, pdu_info_p) >= 0) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index 56b37e1e3953e1e4bcb6af5514ff111966b06b69..7129307739a376f470b6c12ce91422bf67fb8525 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -29,13 +29,12 @@ #include "LAYER2/MAC/mac_extern.h" #include "common/utils/LOG/log.h" //----------------------------------------------------------------------------- -boolean_t rlc_am_nack_pdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_am_entity_t *const rlc_pP, - const rlc_sn_t snP, - const rlc_sn_t prev_nack_snP, - sdu_size_t so_startP, - sdu_size_t so_endP) +bool rlc_am_nack_pdu(const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlc_pP, + const rlc_sn_t snP, + const rlc_sn_t prev_nack_snP, + sdu_size_t so_startP, + sdu_size_t so_endP) { // 5.2.1 Retransmission // ... @@ -54,8 +53,8 @@ boolean_t rlc_am_nack_pdu ( rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer_p = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE]; //int pdu_sdu_index; //int sdu_index; - boolean_t status = TRUE; - boolean_t retx_count_increment = FALSE; + bool status = true; + bool retx_count_increment = false; sdu_size_t pdu_data_to_retx = 0; if (mb_p != NULL) { @@ -63,7 +62,7 @@ boolean_t rlc_am_nack_pdu ( if(so_startP > so_endP) { LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] ERROR NACK MISSING PDU, so_startP %d, so_endP %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),so_startP, so_endP); - status = FALSE; + status = false; } // Handle full PDU NACK first else if ((so_startP == 0) && (so_endP == 0x7FFF)) { @@ -71,9 +70,7 @@ boolean_t rlc_am_nack_pdu ( pdu_data_to_retx = tx_data_pdu_buffer_p->payload_size; /* Increment VtReTxNext if this is the first NACK or if some segments have already been transmitted */ if ((tx_data_pdu_buffer_p->flags.retransmit == 0) || (tx_data_pdu_buffer_p->nack_so_start)) - { - retx_count_increment = TRUE; - } + retx_count_increment = true; tx_data_pdu_buffer_p->nack_so_start = 0; tx_data_pdu_buffer_p->num_holes = 0; @@ -89,11 +86,11 @@ boolean_t rlc_am_nack_pdu ( if(tx_data_pdu_buffer_p->nack_so_start >= tx_data_pdu_buffer_p->payload_size){ LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] ERROR NACK MISSING PDU, nack_so_start %d, payload_size %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),tx_data_pdu_buffer_p->nack_so_start, tx_data_pdu_buffer_p->payload_size); - status = FALSE; + status = false; } } else { - status = FALSE; + status = false; } } else if (tx_data_pdu_buffer_p->flags.max_retransmit == 0) { @@ -107,9 +104,8 @@ boolean_t rlc_am_nack_pdu ( if (prev_nack_snP != snP) { /* New NACK_SN with SO */ /* check whether a new segment is to be placed in Retransmission Buffer, then increment vrReTx */ - if ((tx_data_pdu_buffer_p->flags.retransmit == 0) || (so_startP < tx_data_pdu_buffer_p->nack_so_start)) { - retx_count_increment = TRUE; - } + if ((tx_data_pdu_buffer_p->flags.retransmit == 0) || (so_startP < tx_data_pdu_buffer_p->nack_so_start)) + retx_count_increment = true; tx_data_pdu_buffer_p->num_holes = 1; tx_data_pdu_buffer_p->retx_hole_index = 0; @@ -129,21 +125,18 @@ boolean_t rlc_am_nack_pdu ( tx_data_pdu_buffer_p->nack_so_stop = so_endP; tx_data_pdu_buffer_p->num_holes ++; pdu_data_to_retx = so_endP - so_startP + 1; + } else { + status = false; } - else { - status = FALSE; - } - } - else { - status = FALSE; + } else { + status = false; } } else { - status = FALSE; + status = false; } - } - else { - status = FALSE; + } else { + status = false; } if (status) { @@ -175,17 +168,16 @@ boolean_t rlc_am_nack_pdu ( LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[NACK-PDU] ERROR NACK MISSING PDU SN %05d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), snP); - status = FALSE; + status = false; } return status; } //----------------------------------------------------------------------------- -void rlc_am_ack_pdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_am_entity_t *const rlc_pP, - const rlc_sn_t snP, - boolean_t free_pdu) +void rlc_am_ack_pdu(const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlc_pP, + const rlc_sn_t snP, + bool free_pdu) { mem_block_t* mb_p = rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE].mem_block; rlc_am_tx_data_pdu_management_t *tx_data_pdu_buffer = &rlc_pP->tx_data_pdu_buffer[snP % RLC_AM_WINDOW_SIZE]; @@ -283,7 +275,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( sdu_size_t retx_so_start,retx_so_stop; //starting and ending SO for retransmission in this PDU rlc_sn_t sn = pdu_mngt->sn; uint16_t header_so_part; - boolean_t fi_start, fi_end; + bool fi_start, fi_end; uint8_t sdu_index = 0; uint8_t sdu_segment_index = 0; uint8_t num_LIs_pdu_segment = pdu_mngt->nb_sdus - 1; @@ -377,11 +369,11 @@ mem_block_t* rlc_am_retransmit_get_am_segment( /* Set FI part to false if SO Start and SO End are different from PDU boundaries */ if (retx_so_start) { - fi_start = FALSE; + fi_start = false; } if (retx_so_stop < pdu_mngt->payload_size - 1) { - fi_end = FALSE; + fi_end = false; } /* Header content is filled at the end */ @@ -423,7 +415,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( else { /* if retx_so_start is still not included then set data_size with full original PDU data size */ - /* Set fi_start to FALSE in this case */ + /* Set fi_start to false in this case */ data_size = pdu_mngt->payload_size; } sdu_index ++; @@ -432,7 +424,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( if (retx_so_start == data_size) { /* Set FI Start if retx_so_start = cumulated data size */ - fi_start = TRUE; + fi_start = true; /* there must be at least one SDU more */ //Assertion(eNB)_PRAN_DesignDocument_annex No.778 if(sdu_index >= pdu_mngt->nb_sdus) @@ -464,8 +456,8 @@ mem_block_t* rlc_am_retransmit_get_am_segment( } else if (retx_so_start != 0) { - /* in all other cases set fi_start to FALSE if it SO Start is not 0 */ - fi_start = FALSE; + /* in all other cases set fi_start to false if it SO Start is not 0 */ + fi_start = false; } /* Set first SDU portion of the segment */ @@ -582,10 +574,10 @@ mem_block_t* rlc_am_retransmit_get_am_segment( "RLC AM Tx PDU Segment Data Error: retx_so_stop=%d OriginalPDUDataLength=%d SOStart=%d SegmentLength=%d numLISegment=%d numLIPDU=%d sn=%d LcId=%d !\n", retx_so_stop,pdu_mngt->payload_size,retx_so_start,*payload_sizeP,num_LIs_pdu_segment,pdu_mngt->nb_sdus - 1,sn,rlc_pP->channel_id); */ - /* init FI End to FALSE if retx_so_stop is not end of PDU */ + /* init FI End to false if retx_so_stop is not end of PDU */ if (retx_so_stop != pdu_mngt->payload_size - 1) { - fi_end = FALSE; + fi_end = false; } /* Check consistency between sdus_segment_size and payload_sizeP */ @@ -596,7 +588,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( data_size += sdus_segment_size[i]; if ((retx_so_stop == data_size - 1) && (i < num_LIs_pdu_segment)) { - fi_end = TRUE; + fi_end = true; } } //Assertion(eNB)_PRAN_DesignDocument_annex No.782 @@ -665,7 +657,7 @@ mem_block_t* rlc_am_retransmit_get_am_segment( pdu_mngt->nack_so_start = pdu_mngt->hole_so_start[pdu_mngt->retx_hole_index]; } - /* Content is supposed to be init with 0 so with FIStart=FIEnd=TRUE */ + /* Content is supposed to be init with 0 so with FIStart=FIEnd=true */ RLC_AM_PDU_SET_D_C(*pdu_segment_header_p); RLC_AM_PDU_SET_RF(*pdu_segment_header_p); /* Change FI */ diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h index fc5268931420556c41a4f0ca2af8d25d38f29bad..c34d06337da71763d9d27bf3a1bb46c8cbe8c4cc 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.h @@ -35,7 +35,7 @@ # ifndef __RLC_AM_RETRANSMIT_H__ # define __RLC_AM_RETRANSMIT_H__ //----------------------------------------------------------------------------- -/*! \fn boolean_t rlc_am_nack_pdu (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *rlcP, int16_t snP, int16_t prev_nack_snP,sdu_size_t so_startP, sdu_size_t so_endP) +/*! \fn bool rlc_am_nack_pdu (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *rlcP, int16_t snP, int16_t prev_nack_snP,sdu_size_t so_startP, sdu_size_t so_endP) * \brief The RLC AM PDU which have the sequence number snP is marked NACKed with segment offset fields. * \param[in] ctxtP Running context. * \param[in] rlcP RLC AM protocol instance pointer. @@ -46,13 +46,12 @@ * \return OK/KO * \note It may appear a new hole in the retransmission buffer depending on the segment offset informations. Depending on the state of the retransmission buffer, negative confirmation can be sent to higher layers about the drop by the RLC AM instance of a particular SDU. */ -boolean_t rlc_am_nack_pdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_am_entity_t *const rlcP, - const rlc_sn_t snP, - const rlc_sn_t prev_nack_snP, - sdu_size_t so_startP, - sdu_size_t so_endP); +bool rlc_am_nack_pdu(const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlcP, + const rlc_sn_t snP, + const rlc_sn_t prev_nack_snP, + sdu_size_t so_startP, + sdu_size_t so_endP); /*! \fn void rlc_am_ack_pdu (const protocol_ctxt_t* const ctxt_pP,rlc_am_entity_t *rlcP, rlc_sn_t snP) * \brief The RLC AM PDU which have the sequence number snP is marked ACKed. @@ -62,11 +61,10 @@ boolean_t rlc_am_nack_pdu ( * \param[in] free_pdu Boolean indicating that the PDU can be freed because smaller than new vtA. * \note Depending on the state of the retransmission buffer, positive confirmation can be sent to higher layers about the receiving by the peer RLC AM instance of a particular SDU. */ -void rlc_am_ack_pdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_am_entity_t *const rlcP, - const rlc_sn_t snP, - boolean_t free_pdu); +void rlc_am_ack_pdu(const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlcP, + const rlc_sn_t snP, + bool free_pdu); /*! \fn mem_block_t* rlc_am_retransmit_get_copy (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *rlcP, rlc_sn_t snP) * \brief The RLC AM PDU which have the sequence number snP is marked ACKed. diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 4a065539013f323cb16a146cf2dd07b975ff7a6d..bd578abab2a817d0f97e34eb575d5930ea362cff 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -31,14 +31,13 @@ #include "common/utils/LOG/log.h" -boolean_t rlc_am_rx_check_vr_reassemble( - const protocol_ctxt_t* const ctxt_pP, - const rlc_am_entity_t* const rlc_pP) +bool rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP, + const rlc_am_entity_t* const rlc_pP) { mem_block_t* cursor_p = rlc_pP->receiver_buffer.head; rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = NULL; sdu_size_t next_waited_so = 0; - boolean_t reassemble = FALSE; + bool reassemble = false; if (cursor_p != NULL) { @@ -48,7 +47,7 @@ boolean_t rlc_am_rx_check_vr_reassemble( if (sn_ref != rlc_pP->vr_r) { /* Case vrR has advanced from head : most likely case */ - reassemble = TRUE; + reassemble = true; /* Handle first SN if it is made of PDU segments : set them all to be reassembled */ if (pdu_info_p->rf) { pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); @@ -58,7 +57,7 @@ boolean_t rlc_am_rx_check_vr_reassemble( { LOG_E(RLC, "AM Rx Check Reassembly head SN=%d with PDU segments != vrR=%d should be fully received LCID=%d\n", sn_ref,rlc_pP->vr_r,rlc_pP->channel_id); - return FALSE; + return false; } /* AssertFatal(pdu_cursor_mgnt_p->all_segments_received > 0,"AM Rx Check Reassembly head SN=%d with PDU segments != vrR=%d should be fully received LCID=%d\n", @@ -94,7 +93,7 @@ boolean_t rlc_am_rx_check_vr_reassemble( { LOG_E(RLC, "AM Rx Check Reassembly vr=%d should be partly received SNHead=%d LCID=%d\n", rlc_pP->vr_r,sn_ref,rlc_pP->channel_id); - return FALSE; + return false; } /* AssertFatal(pdu_cursor_mgnt_p->all_segments_received == 0,"AM Rx Check Reassembly vr=%d should be partly received SNHead=%d LCID=%d\n", @@ -123,7 +122,7 @@ boolean_t rlc_am_rx_check_vr_reassemble( { LOG_E(RLC, "AM Rx Check Reassembly SNHead=vr=%d should be partly received LCID=%d\n", rlc_pP->vr_r,rlc_pP->channel_id); - return FALSE; + return false; } /* AssertFatal(pdu_cursor_mgnt_p->all_segments_received == 0,"AM Rx Check Reassembly SNHead=vr=%d should be partly received LCID=%d\n", @@ -132,7 +131,7 @@ boolean_t rlc_am_rx_check_vr_reassemble( while ((cursor_p != NULL) && (pdu_info_p->sn == rlc_pP->vr_r) && (pdu_info_p->so == next_waited_so)) { if (pdu_cursor_mgnt_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO) { pdu_cursor_mgnt_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING; - reassemble = TRUE; + reassemble = true; } next_waited_so += pdu_info_p->payload_size; cursor_p = cursor_p->next; @@ -157,7 +156,7 @@ mem_block_t * create_new_segment_from_pdu( int16_t new_li_list[RLC_AM_MAX_SDU_IN_PDU]; int16_t header_size = 0; uint8_t num_li = 0; - boolean_t fi_start, fi_end, lsf; + bool fi_start, fi_end, lsf; /* Init some PDU Segment header fixed parameters */ fi_start = !((pdu_rx_info_p->fi & 0x2) >> 1); @@ -170,11 +169,11 @@ mem_block_t * create_new_segment_from_pdu( header_size = RLC_AM_PDU_SEGMENT_HEADER_MIN_SIZE; if (so_offset) { - fi_start = FALSE; + fi_start = false; } if (so_offset + data_length_to_copy != pdu_rx_info_p->payload_size) { - fi_end = FALSE; - lsf = FALSE; + fi_end = false; + lsf = false; } } // end no LI in original segment else { @@ -185,7 +184,7 @@ mem_block_t * create_new_segment_from_pdu( /* set LSF to false if we know that end of the original segment will not be copied */ if (so_offset + data_length_to_copy != pdu_rx_info_p->payload_size) { - lsf = FALSE; + lsf = false; } /* catch the first LI containing so_offset */ @@ -223,7 +222,7 @@ mem_block_t * create_new_segment_from_pdu( num_li = j; /* set FI End if remaining size = 0 */ if (remaining_size == 0) { - fi_end = TRUE; + fi_end = true; } } } @@ -263,7 +262,7 @@ mem_block_t * create_new_segment_from_pdu( } /* Fill Header part in the buffer */ - /* Content is supposed to be init with 0 so with FIStart=FIEnd=TRUE */ + /* Content is supposed to be init with 0 so with FIStart=FIEnd=true */ /* copy first two bytes from original: D/C + RF + FI + E+ SN*/ memset(pdu_segment_header_p, 0, header_size); RLC_AM_PDU_SET_D_C(*pdu_segment_header_p); @@ -1106,7 +1105,7 @@ rlc_am_rx_list_reassemble_rlc_sdus( do { if (rlc_am_rx_pdu_management_p->all_segments_received > 0) { cursor_p = list2_remove_head(&rlc_pP->receiver_buffer); - rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p,TRUE); + rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p, true); rlc_am_rx_old_pdu_management = rlc_am_rx_pdu_management_p; cursor_p = list2_get_head(&rlc_pP->receiver_buffer); @@ -1123,7 +1122,7 @@ rlc_am_rx_list_reassemble_rlc_sdus( else if (rlc_am_rx_pdu_management_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING) { rlc_am_rx_pdu_management_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLED; - rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p,FALSE); + rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p, false); rlc_am_rx_old_pdu_management = rlc_am_rx_pdu_management_p; cursor_p = cursor_p->next; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h index fd8704964d1a5fd0f752f0454f80a4ffafb604a6..18e423312cba1a53f40e1198eb2486ebacecfc54 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.h @@ -61,13 +61,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_check_duplicate_insert_pdu(const protocol_ */ signed int rlc_am_rx_list_insert_pdu(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* const rlcP, mem_block_t* const tbP); -/*! \fn boolean_t rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP,const rlc_am_entity_t* const rlc_pP) +/*! \fn bool rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP,const rlc_am_entity_t* const rlc_pP) * \brief Check if reassembly taking into account potential new vrR value * \param[in] ctxt_pP Running context. * \param[in] rlcP RLC AM protocol instance pointer. -* \return TRUE if reassembly must be done, FALSE else +* \return true if reassembly must be done, false else */ -boolean_t rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP,const rlc_am_entity_t* const rlc_pP); +bool rlc_am_rx_check_vr_reassemble(const protocol_ctxt_t* const ctxt_pP,const rlc_am_entity_t* const rlc_pP); /*! \fn void rlc_am_rx_check_all_byte_segments(const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t* const rlcP, mem_block_t* const tbP) * \brief Check if all sub-segments of a PDU are received, if yes then call rlc_am_rx_mark_all_segments_received() procedure. diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c index ed81e119acb2eb4e72a4d53d1373c8d18565ed64..9e7c3338f813eed7e4cd0022da57770d06fa3ab8 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.c @@ -32,12 +32,11 @@ #include "common/utils/LOG/log.h" //----------------------------------------------------------------------------- -void rlc_am_pdu_polling ( - const protocol_ctxt_t* const ctxt_pP, - rlc_am_entity_t *const rlc_pP, - rlc_am_pdu_sn_10_t *const pdu_pP, - const int16_t payload_sizeP, - boolean_t is_new_pdu) +void rlc_am_pdu_polling(const protocol_ctxt_t* const ctxt_pP, + rlc_am_entity_t *const rlc_pP, + rlc_am_pdu_sn_10_t *const pdu_pP, + const int16_t payload_sizeP, + bool is_new_pdu) { // 5.2.2 Polling // An AM RLC entity can poll its peer AM RLC entity in order to trigger STATUS reporting at the peer AM RLC entity. diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h index dc754d08e498b61024e00dffd194c4a4aa44da5e..1e472302c82effd27fdf38c92218d65e3a91c897 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_segment.h @@ -36,14 +36,14 @@ # define __RLC_AM_SEGMENT_H__ //----------------------------------------------------------------------------- -/*! \fn void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP,boolean_t is_new_pdu) +/*! \fn void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP, bool is_new_pdu) * \brief Set or not the poll bit in the PDU header depending on RLC AM protocol variables. * \param[in] ctxt_pP Running context. * \param[in] rlcP RLC AM protocol instance pointer. * \param[in] pduP Pointer on the header of the PDU in order to be able to set the poll bit if necessary. * \param[in] payload_sizeP Size of the payload of the PDU. */ -void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP,boolean_t is_new_pdu); +void rlc_am_pdu_polling (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t *const rlcP, rlc_am_pdu_sn_10_t *pduP, int16_t payload_sizeP, bool is_new_pdu); /*! \fn void rlc_am_segment_10 (const protocol_ctxt_t* const ctxt_pP, rlc_am_entity_t * const rlcP) * \brief Segment a PDU with 10 bits sequence number, based on segmentation information given by MAC (size to transmit). diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index 02a0247a03d2e8a3c8dc0e498a364838506d33bf..f1e6c961e704ee5ce26cf9a5b1dce2d1512cb02c 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -237,7 +237,7 @@ rlc_am_receive_process_control_pdu( rlc_sn_t nack_sn,prev_nack_sn; sdu_size_t data_cnf_so_stop = 0x7FFF; unsigned int nack_index; - boolean_t status = TRUE; + bool status = true; if (rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10_p, tb_size_in_bytes_pP, &rlc_pP->control_pdu_info) >= 0) { rlc_am_tx_buffer_display(ctxt_pP, rlc_pP, " TX BUFFER BEFORE PROCESS OF STATUS PDU"); @@ -282,7 +282,7 @@ rlc_am_receive_process_control_pdu( if (RLC_AM_DIFF_SN(rlc_pP->vt_s,rlc_pP->vt_a) >= RLC_AM_DIFF_SN(ack_sn,rlc_pP->vt_a)) { if (rlc_pP->control_pdu_info.num_nack == 0) { while (sn_cursor != ack_sn) { - rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor,TRUE); + rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor, true); sn_cursor = RLC_AM_NEXT_SN(sn_cursor); } @@ -294,7 +294,7 @@ rlc_am_receive_process_control_pdu( prev_nack_sn = 0x3FFF; while (sn_cursor != nack_sn) { - rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor,TRUE); + rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor, true); sn_cursor = RLC_AM_NEXT_SN(sn_cursor); } @@ -316,7 +316,7 @@ rlc_am_receive_process_control_pdu( rlc_am_ack_pdu(ctxt_pP, rlc_pP, sn_cursor, - FALSE); + false); } else { status = rlc_am_nack_pdu (ctxt_pP, rlc_pP, @@ -348,13 +348,13 @@ rlc_am_receive_process_control_pdu( LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" WARNING CONTROL PDU ACK SN %d OUT OF WINDOW vtA=%d vtS=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),ack_sn,rlc_pP->vt_a,rlc_pP->vt_s); *tb_size_in_bytes_pP = 0; - status = FALSE; + status = false; } } else { LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" ERROR IN DECODING CONTROL PDU\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); *tb_size_in_bytes_pP = 0; - status = FALSE; + status = false; } if (status) { @@ -480,8 +480,8 @@ rlc_am_send_status_pdu( int waited_so = 0; mem_block_t *tb_p = NULL; sdu_size_t pdu_size = 0; - boolean_t status_report_completed = false; - boolean_t segment_loop_end = false; + bool status_report_completed = false; + bool segment_loop_end = false; memset(&control_pdu_info, 0, sizeof(rlc_am_control_pdu_info_t)); LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[SEND-STATUS] nb_bits_to_transmit %d (15 already allocated for header)\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c index 7a95a62787a58c65e114ca76bf4723e2c9c15ade..e898a601c2c7759ac41a12fffd947e4556d29b33 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_test.c @@ -1170,7 +1170,7 @@ void rlc_am_v9_3_0_test(void) { // initscr(); // cbreak(); - // keypad(stdscr, TRUE); + // keypad(stdscr, true); // under test pool_buffer_init(); set_comp_log(RLC, LOG_ERR, LOG_MED, 1); diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c index 969ed2d7a54815a085786c84c4aece717c5e087a..7aead2f30a46aa64a9e79207db673ed9af911aed 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_timer_poll_retransmit.c @@ -111,7 +111,7 @@ rlc_am_check_timer_poll_retransmit( } - rlc_pP->force_poll= TRUE; + rlc_pP->force_poll = true; //BugFix : new ms_time_out is computed when next poll is transmitter } } diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c index 4e3fffe176e3ba32917a38bf44c9d13e21536fc8..f079696aa911d8491cb6b0bf1e9db3e0c4d58763 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.c @@ -31,13 +31,11 @@ #include "list.h" #include "LAYER2/MAC/mac_extern.h" //----------------------------------------------------------------------------- -void -rlc_tm_send_sdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_tm_entity_t * const rlc_pP, - const boolean_t error_indicationP, - uint8_t * const srcP, - const sdu_size_t length_in_bitsP) +void rlc_tm_send_sdu(const protocol_ctxt_t* const ctxt_pP, + rlc_tm_entity_t * const rlc_pP, + const bool error_indicationP, + uint8_t * const srcP, + const sdu_size_t length_in_bitsP) { int length_in_bytes; #if DEBUG_RLC_TM_DISPLAY_ASCII_DATA diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h index d2bab33b1a428fe703cac72a8fd094c5b9f35a0c..de7b9b8170673969f6713ba3b59983de27f03e90 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm.h @@ -51,7 +51,7 @@ /*! \fn void rlc_tm_send_sdu ( * const protocol_ctxt_t* const ctxt_pP, * rlc_tm_entity_t * const rlc_pP, -* const boolean_t error_indicationP, +* const bool error_indicationP, * uint8_t * const srcP, * const sdu_size_t length_in_bitsP) * \brief Send SDU if any reassemblied to upper layer. @@ -60,12 +60,11 @@ * \param[in] srcP SDU data pointer. * \param[in] length_in_bitsP Length of SDU in bits. */ -void rlc_tm_send_sdu ( - const protocol_ctxt_t* const ctxt_pP, - rlc_tm_entity_t * const rlc_pP, - const boolean_t error_indicationP, - uint8_t * const srcP, - const sdu_size_t length_in_bitsP); +void rlc_tm_send_sdu(const protocol_ctxt_t* const ctxt_pP, + rlc_tm_entity_t * const rlc_pP, + const bool error_indicationP, + uint8_t * const srcP, + const sdu_size_t length_in_bitsP); /*! \fn void rlc_tm_no_segment (const protocol_ctxt_t* const ctxt_pP, rlc_tm_entity_t * const rlcP) * \brief Schedule a SDU to be transmited by lower layers. diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_entity.h b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_entity.h index 1a13982df65fd2bac70d02dae4452c7ea0711e0c..3c2f1804bec6eff71530fc36032252d772b45f24 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_entity.h +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_entity.h @@ -40,14 +40,13 @@ * \brief Structure containing a RLC TM instance protocol variables, allocation variables, buffers and other miscellaneous variables. */ typedef struct rlc_tm_entity { - boolean_t allocation; /*!< \brief Boolean for rlc_tm_entity_t struct allocation. */ + bool allocation; /*!< \brief Boolean for rlc_tm_entity_t struct allocation. */ rlc_protocol_state_t protocol_state; /*!< \brief Protocol state, can be RLC_NULL_STATE, RLC_DATA_TRANSFER_READY_STATE, RLC_LOCAL_SUSPEND_STATE. */ - boolean_t is_uplink_downlink; /*!< \brief Is this instance is a transmitter, a receiver or both? */ - boolean_t is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ + bool is_uplink_downlink; /*!< \brief Is this instance is a transmitter, a receiver or both? */ + bool is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ // for stats and trace purpose : logical_chan_id_t channel_id; /*!< \brief Transport channel identifier. */ rb_id_t rb_id; /*!< \brief Radio bearer identifier, for statistics and trace purpose. */ - //boolean_t is_enb; /*!< \brief To know if the RLC belongs to a eNB or UE. */ //----------------------------- // tranmission //----------------------------- diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c index 22e6f4d78d1a4d1b8d0dc4c855216bda7068caed..a838b2a00663e0ebb6706605b1379232da9d51de 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.c @@ -133,10 +133,9 @@ rlc_tm_cleanup ( } //----------------------------------------------------------------------------- -void rlc_tm_configure( - const protocol_ctxt_t* const ctxt_pP, - rlc_tm_entity_t * const rlcP, - const boolean_t is_uplink_downlinkP) +void rlc_tm_configure(const protocol_ctxt_t* const ctxt_pP, + rlc_tm_entity_t * const rlcP, + const bool is_uplink_downlinkP) { rlcP->is_uplink_downlink = is_uplink_downlinkP; rlc_tm_reset_state_variables (ctxt_pP, rlcP); diff --git a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h index 57e2116a724969c37e538659628791263cb6ebb8..f315a0311ae3badd25a06753b4974abed62b8c38 100644 --- a/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h +++ b/openair2/LAYER2/RLC/TM_v9.3.0/rlc_tm_init.h @@ -78,27 +78,24 @@ void rlc_tm_init ( * \brief Reset protocol variables and state variables to initial values. * \param[in] rlcP RLC TM protocol instance pointer. */ -void rlc_tm_reset_state_variables ( - const protocol_ctxt_t* const ctxt_pP, - rlc_tm_entity_t * const rlcP); +void rlc_tm_reset_state_variables(const protocol_ctxt_t* const ctxt_pP, + rlc_tm_entity_t * const rlcP); /*! \fn void rlc_tm_cleanup(rlc_tm_entity_t * const rlcP) * \brief Free all allocated memory (lists and buffers) previously allocated by this RLC TM instance. * \param[in] rlcP RLC TM protocol instance pointer. */ -void rlc_tm_cleanup( - rlc_tm_entity_t * const rlcP); +void rlc_tm_cleanup(rlc_tm_entity_t * const rlcP); -/*! \fn void rlc_tm_configure(const protocol_ctxt_t* const ctxt_pP,rlc_tm_entity_t * const rlcP, const boolean_t is_uplink_downlinkP) +/*! \fn void rlc_tm_configure(const protocol_ctxt_t* const ctxt_pP,rlc_tm_entity_t * const rlcP, const bool is_uplink_downlinkP) * \brief Configure RLC TM protocol parameters. * \param[in] rlcP RLC TM protocol instance pointer. * \param[in] is_uplink_downlinkP Is this instance is TRANSMITTER_ONLY, RECEIVER_ONLY, or TRANSMITTER_AND_RECEIVER. */ -void rlc_tm_configure( - const protocol_ctxt_t* const ctxt_pP, - rlc_tm_entity_t * const rlcP, - const boolean_t is_uplink_downlinkP); +void rlc_tm_configure(const protocol_ctxt_t* const ctxt_pP, + rlc_tm_entity_t * const rlcP, + const bool is_uplink_downlinkP); /*! \fn void rlc_tm_set_debug_infos(const protocol_ctxt_t* const ctxt_pP, rlc_tm_entity_t * const rlcP, const rb_id_t rb_idP, const srb_flag_t srb_flagP) * \brief Set debug informations for a RLC TM protocol instance, these informations are only for trace purpose. diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c index bec815ac5da6a93d4c96daaeaae2a4a611e69282..f2cb4f09b1e3227851a004c8d0271021ab101523 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_control_primitives.c @@ -263,7 +263,7 @@ rlc_um_init ( } rlc_pP->first_pdu = 1; - rlc_pP->initialized = TRUE; + rlc_pP->initialized = true; } } //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_entity.h b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_entity.h index 3250ac85b85c925cfaea642af929f200eecd4752..7bfa3d60ffe6f8c4ba104c9357f9689dd22d21de 100644 --- a/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_entity.h +++ b/openair2/LAYER2/RLC/UM_v9.3.0/rlc_um_entity.h @@ -53,12 +53,11 @@ typedef struct rlc_um_timer_s { */ typedef struct rlc_um_entity_s { - boolean_t initialized; /*!< \brief Boolean for rlc_am_entity_t struct initialization. */ - boolean_t is_uplink_downlink; /*!< \brief Is this instance is a transmitter, a receiver or both? */ + bool initialized; /*!< \brief Boolean for rlc_am_entity_t struct initialization. */ + bool is_uplink_downlink; /*!< \brief Is this instance is a transmitter, a receiver or both? */ rlc_protocol_state_t protocol_state; /*!< \brief Protocol state, can be RLC_NULL_STATE, RLC_DATA_TRANSFER_READY_STATE, RLC_LOCAL_SUSPEND_STATE. */ - boolean_t is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ - //boolean_t is_enb; /*!< \brief To know if the RLC belongs to a eNB or UE. */ - boolean_t is_mxch; /*!< \brief To know if the RLC belongs to a MBMS bearer. */ + bool is_data_plane; /*!< \brief To know if the RLC belongs to a data radio bearer or a signalling radio bearer, for statistics and trace purpose. */ + bool is_mxch; /*!< \brief To know if the RLC belongs to a MBMS bearer. */ //----------------------------- // PROTOCOL VARIABLES //----------------------------- @@ -114,7 +113,7 @@ typedef struct rlc_um_entity_s { //----------------------------- // STATISTICS //----------------------------- - boolean_t first_pdu; /*!< \brief Act as a boolean, tells if the next PDU is the first PDU to be received. */ + bool first_pdu; /*!< \brief Act as a boolean, tells if the next PDU is the first PDU to be received. */ unsigned int stat_tx_pdcp_sdu; /*!< \brief Number of SDUs received from upper layers. */ unsigned int stat_tx_pdcp_bytes; /*!< \brief Number of SDU bytes received from upper layers. */ diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index b9dcf0414b99024195fe1a6bdc26f4ba7e10ef06..ec90817500d55bdf30b901518754e05f7a08f9cb 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -41,13 +41,12 @@ #include "common/ran_context.h" extern RAN_CONTEXT_t RC; -extern boolean_t pdcp_data_ind( - const protocol_ctxt_t *const ctxt_pP, - const srb_flag_t srb_flagP, - const MBMS_flag_t MBMS_flagP, - const rb_id_t rb_idP, - const sdu_size_t sdu_buffer_sizeP, - mem_block_t *const sdu_buffer_pP); +extern bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, + const sdu_size_t sdu_buffer_sizeP, + mem_block_t *const sdu_buffer_pP); #define DEBUG_RLC_PDCP_INTERFACE 1 //#define TRACE_RLC_PAYLOAD 1 @@ -397,7 +396,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_IN); - if (MBMS_flagP == TRUE) { + if (MBMS_flagP == true) { if (ctxt_pP->enb_flag) { log_ch_id = rlc_mbms_enb_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP); mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][log_ch_id]; diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 1e5b7947d7a384f209776fce7a9af2136e3eda04..1e17ff96bfcfa2a8060040dba9465b4a23163f2b 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -107,7 +107,7 @@ typedef struct { rlc_buffer_occupancy_t pdus_in_buffer; /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */ frame_t head_sdu_creation_time; /*!< \brief Head SDU creation time. */ sdu_size_t head_sdu_remaining_size_to_send; /*!< \brief remaining size of sdu: could be the total size or the remaining size of already segmented sdu */ - boolean_t head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ + bool head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */ } mac_rlc_status_resp_t; diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index 89cbe4c406c0e34dc0c981ffd9e66d6c634c56a7..0e1cb89fd7145262489f9c44269f4bc2c80826ee 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -425,8 +425,8 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( /* Assumptions : for UE only */ /* At each TTI, Buffer Occupancy is first computed in mac_rlc_status_ind called by MAC ue_scheduler() function */ /* Then this function is called during MAC multiplexing ue_get_sdu(), and it may be call several times for the same bearer if it is in AM mode and there are several PDU types to transmit */ - //AssertFatal(enb_flagP == FALSE,"RLC Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%d\n", channel_idP); - if(enb_flagP != FALSE) { + //AssertFatal(enb_flagP == false,"RLC Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%d\n", channel_idP); + if(enb_flagP != false) { LOG_E(RLC, "Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%u\n", channel_idP); return 0; } diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index 4313f379fe0f9e5475dbd8053215f0c73567f5d8..ed9af5efb2541c46d87c8a30637c46b06565022e 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -480,7 +480,7 @@ rlc_op_status_t rrc_rlc_remove_rlc ( /* for no gcc warnings */ (void)lcid; - if (MBMS_flagP == TRUE) { + if (MBMS_flagP == true) { if (ctxt_pP->enb_flag) { lcid = rlc_mbms_enb_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP); mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid]; @@ -581,7 +581,7 @@ rlc_union_t *rrc_rlc_add_rlc ( rlc_mbms_id_t *mbms_id_p = NULL; logical_chan_id_t lcid = 0; - if (MBMS_flagP == FALSE) { + if (MBMS_flagP == false) { //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX); //AssertFatal (chan_idP < RLC_MAX_LC, "LC id is too high (%u/%d)!\n", chan_idP, RLC_MAX_LC); if(rb_idP >= NB_RB_MAX) { @@ -595,7 +595,7 @@ rlc_union_t *rrc_rlc_add_rlc ( } } - if (MBMS_flagP == TRUE) { + if (MBMS_flagP == true) { if (ctxt_pP->enb_flag) { lcid = rlc_mbms_enb_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP); mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lcid]; @@ -640,11 +640,11 @@ rlc_union_t *rrc_rlc_add_rlc ( } else if (h_rc == HASH_TABLE_KEY_NOT_EXISTS) { rlc_union_p = calloc(1, sizeof(rlc_union_t)); h_rc = hashtable_insert(rlc_coll_p, key, rlc_union_p); - if(MBMS_flagP != TRUE) + if(MBMS_flagP != true) h_lcid_rc = hashtable_insert(rlc_coll_p, key_lcid, rlc_union_p); if ((h_rc == HASH_TABLE_OK) && (h_lcid_rc == HASH_TABLE_OK)) { - if (MBMS_flagP == TRUE) { + if (MBMS_flagP == true) { LOG_I(RLC, PROTOCOL_CTXT_FMT" RLC service id %u session id %u rrc_rlc_add_rlc\n", PROTOCOL_CTXT_ARGS(ctxt_pP), mbms_id_p->service_id, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 7e1ddb62bd87ab94100d7863029897f1916dd86d..480b651593f0bdc027ecb438eb4cd4ddd4a7add9 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -27,6 +27,7 @@ #include "nr_pdcp_security_nea2.h" #include "nr_pdcp_integrity_nia2.h" +#include "nr_pdcp_integrity_nia1.h" #include "nr_pdcp_sdu.h" #include "LOG/log.h" @@ -240,16 +241,21 @@ static void nr_pdcp_entity_set_security(nr_pdcp_entity_t *entity, } if (integrity_algorithm != 0 && integrity_algorithm != -1) { - if (integrity_algorithm != 2) { - LOG_E(PDCP, "FATAL: only nia2 supported for the moment\n"); - exit(1); - } entity->has_integrity = 1; if (entity->free_integrity != NULL) entity->free_integrity(entity->integrity_context); - entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key); - entity->integrity = nr_pdcp_integrity_nia2_integrity; - entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity; + if (integrity_algorithm == 2) { + entity->integrity_context = nr_pdcp_integrity_nia2_init(entity->integrity_key); + entity->integrity = nr_pdcp_integrity_nia2_integrity; + entity->free_integrity = nr_pdcp_integrity_nia2_free_integrity; + } else if (integrity_algorithm == 1) { + entity->integrity_context = nr_pdcp_integrity_nia1_init(entity->integrity_key); + entity->integrity = nr_pdcp_integrity_nia1_integrity; + entity->free_integrity = nr_pdcp_integrity_nia1_free_integrity; + } else { + LOG_E(PDCP, "FATAL: only nia1 and nia2 supported for the moment\n"); + exit(1); + } } if (ciphering_algorithm == 0) { diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c new file mode 100644 index 0000000000000000000000000000000000000000..08ec95993703e6ae6ab25d3383dbc5c2a9e69ece --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c @@ -0,0 +1,66 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_pdcp_integrity_nia1.h" + +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <openssl/cmac.h> + +#include "UTIL/OSA/osa_defs.h" + +int stream_compute_integrity_eia1(stream_cipher_t *stream_cipher, uint8_t out[4]); + +void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key) +{ + stream_cipher_t *ret; + + ret = calloc(1, sizeof(*ret)); if (ret == NULL) abort(); + ret->key = malloc(16); if (ret->key == NULL) abort(); + memcpy(ret->key, integrity_key, 16); + ret->key_length = 16; /* unused */ + + return ret; +} + +void nr_pdcp_integrity_nia1_integrity(void *integrity_context, + unsigned char *out, + unsigned char *buffer, int length, + int bearer, int count, int direction) +{ + stream_cipher_t *ctx = integrity_context; + + ctx->message = buffer; + ctx->count = count; + ctx->bearer = bearer-1; + ctx->direction = direction; + ctx->blength = length * 8; + + stream_compute_integrity_eia1(ctx, out); +} + +void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context) +{ + stream_cipher_t *ctx = integrity_context; + free(ctx->key); + free(ctx); +} diff --git a/openair2/COMMON/itti_sim_messages_types.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h similarity index 53% rename from openair2/COMMON/itti_sim_messages_types.h rename to openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h index 2e29e8f508e1508dd012d9cc88b3a1185c95cafa..5c44bad4a7dbdeb2e515b6f3d7dd850b0b1f2764 100644 --- a/openair2/COMMON/itti_sim_messages_types.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h @@ -19,33 +19,16 @@ * contact@openairinterface.org */ -/*! \file itti_sim_messages_types.h - * \brief itti message for itti simulator - * \author Yoshio INOUE, Masayuki HARADA - * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com - * \date 2020 - * \version 0.1 - */ - -#ifndef ITTI_SIM_MESSAGES_TYPES_H_ -#define ITTI_SIM_MESSAGES_TYPES_H_ - -#include "LTE_asn_constant.h" - - - -#define GNB_RRC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBBCCHind -#define GNB_RRC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBCCCHind -#define GNB_RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.GNBDCCHind -#define UE_RRC_CCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.UECCCHind -#define UE_RRC_DCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.UEDCCHind +#ifndef _NR_PDCP_INTEGRITY_NIA1_H_ +#define _NR_PDCP_INTEGRITY_NIA1_H_ +void *nr_pdcp_integrity_nia1_init(unsigned char *integrity_key); +void nr_pdcp_integrity_nia1_integrity(void *integrity_context, + unsigned char *out, + unsigned char *buffer, int length, + int bearer, int count, int direction); -typedef struct itti_sim_rrc_ch_s { - rb_id_t rbid; - uint8_t *sdu; - int size; -} itti_sim_rrc_ch_t; +void nr_pdcp_integrity_nia1_free_integrity(void *integrity_context); -#endif /* ITTI_SIM_MESSAGES_TYPES_H_ */ +#endif /* _NR_PDCP_INTEGRITY_NIA1_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index ea4b7e80c7651445bb0989e5dfd0abbea017ff5f..47c630e0c962f48bc94df652debdab3ce60153d9 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -274,9 +274,8 @@ static void do_pdcp_data_ind( if (rb != NULL) { rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size); } else { - LOG_E(PDCP, "%s:%d:%s: fatal: no RB found (rb_id %ld, srb_flag %d)\n", + LOG_E(PDCP, "%s:%d:%s: no RB found (rb_id %ld, srb_flag %d)\n", __FILE__, __LINE__, __FUNCTION__, rb_id, srb_flagP); - exit(1); } nr_pdcp_manager_unlock(nr_pdcp_ue_manager); @@ -360,15 +359,14 @@ static void enqueue_pdcp_data_ind( if (pthread_mutex_unlock(&pq.m) != 0) abort(); } -boolean_t pdcp_data_ind( - const protocol_ctxt_t *const ctxt_pP, - const srb_flag_t srb_flagP, - const MBMS_flag_t MBMS_flagP, - const rb_id_t rb_id, - const sdu_size_t sdu_buffer_size, - mem_block_t *const sdu_buffer, - const uint32_t *const srcID, - const uint32_t *const dstID) +bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_id, + const sdu_size_t sdu_buffer_size, + mem_block_t *const sdu_buffer, + const uint32_t *const srcID, + const uint32_t *const dstID) { enqueue_pdcp_data_ind(ctxt_pP, srb_flagP, @@ -439,7 +437,7 @@ static void *enb_tun_read_thread(void *_) ctxt.rnti = rnti; uint8_t qfi = 7; - boolean_t rqi = 0; + bool rqi = 0; int pdusession_id = 10; sdap_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED, @@ -485,13 +483,13 @@ static void *ue_tun_read_thread(void *_) ctxt.rnti = rnti; - boolean_t dc = SDAP_HDR_UL_DATA_PDU; - uint8_t qfi = 7; - int pdusession_id = 10; + bool dc = SDAP_HDR_UL_DATA_PDU; + extern uint8_t nas_qfi; + extern uint8_t nas_pduid; sdap_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf, - PDCP_TRANSMISSION_MODE_DATA, NULL, NULL, qfi, dc, pdusession_id); + PDCP_TRANSMISSION_MODE_DATA, NULL, NULL, nas_qfi, dc, nas_pduid); } return NULL; @@ -593,8 +591,10 @@ uint64_t nr_pdcp_module_init(uint64_t _pdcp_optmask, int id) int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 || NFAPI_MODE == NFAPI_MODE_STANDALONE_PNF)? MAX_MOBILES_PER_ENB : 1; netlink_init_tun(ifsuffix_ue, num_if, id); //Add --nr-ip-over-lte option check for next line - if (IS_SOFTMODEM_NOS1) - nas_config(1, 1, !get_softmodem_params()->nsa ? 2 : 3, ifsuffix_ue); + if (IS_SOFTMODEM_NOS1){ + nas_config(1, 1, !get_softmodem_params()->nsa ? 2 : 3, ifsuffix_ue); + set_qfi_pduid(7, 10); + } LOG_I(PDCP, "UE pdcp will use tun interface\n"); start_pdcp_tun_ue(); } else if(ENB_NAS_USE_TUN) { @@ -736,27 +736,30 @@ static void deliver_sdu_srb(void *_ue, nr_pdcp_entity_t *entity, __FILE__, __LINE__, __FUNCTION__, ue->rnti); exit(1); - srb_found: - { - uint8_t *rrc_buffer_p = entity->is_gnb ? - itti_malloc(TASK_PDCP_ENB, TASK_RRC_GNB, size): - itti_malloc(TASK_PDCP_UE, TASK_RRC_NRUE, size); - MessageDef *message_p; - - AssertFatal(rrc_buffer_p != NULL, "OUT OF MEMORY"); - memcpy(rrc_buffer_p, buf, size); - message_p = entity->is_gnb ? - itti_alloc_new_message(TASK_PDCP_ENB, 0, NR_RRC_DCCH_DATA_IND): - itti_alloc_new_message(TASK_PDCP_UE, 0, NR_RRC_DCCH_DATA_IND); - - AssertFatal(message_p != NULL, "OUT OF MEMORY"); - NR_RRC_DCCH_DATA_IND(message_p).dcch_index = srb_id; - NR_RRC_DCCH_DATA_IND(message_p).sdu_p = rrc_buffer_p; - NR_RRC_DCCH_DATA_IND(message_p).sdu_size = size; - NR_RRC_DCCH_DATA_IND(message_p).rnti = ue->rnti; - - itti_send_msg_to_task(entity->is_gnb ? TASK_RRC_GNB : TASK_RRC_NRUE, 0, message_p); - } +srb_found: + if (entity->is_gnb) { + MessageDef *message_p = itti_alloc_new_message(TASK_PDCP_GNB, 0, F1AP_UL_RRC_MESSAGE); + AssertFatal(message_p != NULL, "OUT OF MEMORY\n"); + f1ap_ul_rrc_message_t *ul_rrc = &F1AP_UL_RRC_MESSAGE(message_p); + ul_rrc->rnti = ue->rnti; + ul_rrc->srb_id = srb_id; + ul_rrc->rrc_container = malloc(size); + AssertFatal(ul_rrc->rrc_container != NULL, "OUT OF MEMORY\n"); + memcpy(ul_rrc->rrc_container, buf, size); + ul_rrc->rrc_container_length = size; + itti_send_msg_to_task(TASK_RRC_GNB, 0, message_p); + } else { + uint8_t *rrc_buffer_p = itti_malloc(TASK_PDCP_UE, TASK_RRC_NRUE, size); + AssertFatal(rrc_buffer_p != NULL, "OUT OF MEMORY\n"); + memcpy(rrc_buffer_p, buf, size); + MessageDef *message_p = itti_alloc_new_message(TASK_PDCP_UE, 0, NR_RRC_DCCH_DATA_IND); + AssertFatal(message_p != NULL, "OUT OF MEMORY\n"); + NR_RRC_DCCH_DATA_IND(message_p).dcch_index = srb_id; + NR_RRC_DCCH_DATA_IND(message_p).sdu_p = rrc_buffer_p; + NR_RRC_DCCH_DATA_IND(message_p).sdu_size = size; + NR_RRC_DCCH_DATA_IND(message_p).rnti = ue->rnti; + itti_send_msg_to_task(TASK_RRC_NRUE, 0, message_p); + } } static void deliver_pdu_srb(void *_ue, nr_pdcp_entity_t *entity, @@ -859,7 +862,7 @@ void pdcp_run(const protocol_ctxt_t *const ctxt_pP) RRC_DCCH_DATA_REQ(msg_p).mode, NULL, NULL); - if (result != TRUE) + if (result != true) LOG_E(PDCP, "PDCP data request failed!\n"); result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ(msg_p).sdu_p); AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); @@ -951,7 +954,7 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, int has_sdap = 0; int has_sdapULheader=0; int has_sdapDLheader=0; - boolean_t is_sdap_DefaultDRB = false; + bool is_sdap_DefaultDRB = false; NR_QFI_t *mappedQFIs2Add = NULL; uint8_t mappedQFIs2AddCount=0; if (s->cnAssociation->present == NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity) @@ -1034,20 +1037,18 @@ static void add_drb(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s, LOG_I(PDCP, "%s:%s:%d: added DRB for UE RNTI %x\n", __FILE__, __FUNCTION__, __LINE__, rnti); } -boolean_t nr_rrc_pdcp_config_asn1_req( - const protocol_ctxt_t *const ctxt_pP, - NR_SRB_ToAddModList_t *const srb2add_list, - NR_DRB_ToAddModList_t *const drb2add_list, - NR_DRB_ToReleaseList_t *const drb2release_list, - const uint8_t security_modeP, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc, - uint8_t *const kUPint - ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 - ,rb_id_t *const defaultDRB, - struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list) - //struct NR_RLC_Config *rlc_Config) +bool nr_rrc_pdcp_config_asn1_req(const protocol_ctxt_t *const ctxt_pP, + NR_SRB_ToAddModList_t *const srb2add_list, + NR_DRB_ToAddModList_t *const drb2add_list, + NR_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc, + uint8_t *const kUPint, + LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9, + rb_id_t *const defaultDRB, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list) { int rnti = ctxt_pP->rnti; int i; @@ -1105,17 +1106,16 @@ boolean_t nr_rrc_pdcp_config_asn1_req( } /* Dummy function due to dependency from LTE libraries */ -boolean_t rrc_pdcp_config_asn1_req( - const protocol_ctxt_t *const ctxt_pP, - LTE_SRB_ToAddModList_t *const srb2add_list, - LTE_DRB_ToAddModList_t *const drb2add_list, - LTE_DRB_ToReleaseList_t *const drb2release_list, - const uint8_t security_modeP, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc - ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 - ,rb_id_t *const defaultDRB) +bool rrc_pdcp_config_asn1_req(const protocol_ctxt_t *const ctxt_pP, + LTE_SRB_ToAddModList_t *const srb2add_list, + LTE_DRB_ToAddModList_t *const drb2add_list, + LTE_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc, + LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9, + rb_id_t *const defaultDRB) { return 0; } @@ -1220,8 +1220,7 @@ uint64_t get_pdcp_optmask(void) return pdcp_optmask; } -boolean_t pdcp_remove_UE( - const protocol_ctxt_t *const ctxt_pP) +bool pdcp_remove_UE(const protocol_ctxt_t *const ctxt_pP) { int rnti = ctxt_pP->rnti; @@ -1276,13 +1275,12 @@ void pdcp_config_set_security( nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -static boolean_t pdcp_data_req_srb( - protocol_ctxt_t *ctxt_pP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer) +static bool pdcp_data_req_srb(protocol_ctxt_t *ctxt_pP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer) { LOG_D(PDCP, "%s() called, size %d\n", __func__, sdu_buffer_size); nr_pdcp_ue_t *ue; @@ -1323,13 +1321,12 @@ static boolean_t pdcp_data_req_srb( } -static boolean_t pdcp_data_req_drb( - protocol_ctxt_t *ctxt_pP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer) +static bool pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer) { LOG_D(PDCP, "%s() called, size %d\n", __func__, sdu_buffer_size); nr_pdcp_ue_t *ue; @@ -1369,19 +1366,16 @@ static boolean_t pdcp_data_req_drb( return 1; } -boolean_t cu_f1u_data_req( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t mode - ,const uint32_t *const sourceL2Id - ,const uint32_t *const destinationL2Id - ) { - +bool cu_f1u_data_req(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode, + const uint32_t *const sourceL2Id, + const uint32_t *const destinationL2Id) { //Force instance id to 0, OAI incoherent instance management ctxt_pP->instance=0; mem_block_t *memblock = get_free_mem_block(sdu_buffer_size, __func__); @@ -1398,18 +1392,16 @@ boolean_t cu_f1u_data_req( return ret; } -boolean_t pdcp_data_req( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_id, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t mode - ,const uint32_t *const sourceL2Id - ,const uint32_t *const destinationL2Id - ) +bool pdcp_data_req(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode, + const uint32_t *const sourceL2Id, + const uint32_t *const destinationL2Id) { if (srb_flagP) { return pdcp_data_req_srb(ctxt_pP, rb_id, muiP, confirmP, sdu_buffer_size, sdu_buffer); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c index fefe2fc77d4bf6a4ca606343133579cd4f2ecc2c..1883bbdd6cc0400debd3465cca665c34b82005bc 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.c @@ -77,14 +77,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_am( ret->sn_modulus = 1 << ret->sn_field_length; ret->window_size = ret->sn_modulus / 2; - ret->common.recv_pdu = nr_rlc_entity_am_recv_pdu; - ret->common.buffer_status = nr_rlc_entity_am_buffer_status; - ret->common.generate_pdu = nr_rlc_entity_am_generate_pdu; - ret->common.recv_sdu = nr_rlc_entity_am_recv_sdu; - ret->common.set_time = nr_rlc_entity_am_set_time; - ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu; - ret->common.reestablishment = nr_rlc_entity_am_reestablishment; - ret->common.delete = nr_rlc_entity_am_delete; + ret->common.recv_pdu = nr_rlc_entity_am_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_am_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_am_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_am_recv_sdu; + ret->common.set_time = nr_rlc_entity_am_set_time; + ret->common.discard_sdu = nr_rlc_entity_am_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_am_reestablishment; + ret->common.delete = nr_rlc_entity_am_delete; + ret->common.available_tx_space = nr_rlc_entity_am_available_tx_space; ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu_data = deliver_sdu_data; @@ -127,14 +128,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_um( ret->sn_modulus = 1 << ret->sn_field_length; ret->window_size = ret->sn_modulus / 2; - ret->common.recv_pdu = nr_rlc_entity_um_recv_pdu; - ret->common.buffer_status = nr_rlc_entity_um_buffer_status; - ret->common.generate_pdu = nr_rlc_entity_um_generate_pdu; - ret->common.recv_sdu = nr_rlc_entity_um_recv_sdu; - ret->common.set_time = nr_rlc_entity_um_set_time; - ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu; - ret->common.reestablishment = nr_rlc_entity_um_reestablishment; - ret->common.delete = nr_rlc_entity_um_delete; + ret->common.recv_pdu = nr_rlc_entity_um_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_um_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_um_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_um_recv_sdu; + ret->common.set_time = nr_rlc_entity_um_set_time; + ret->common.discard_sdu = nr_rlc_entity_um_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_um_reestablishment; + ret->common.delete = nr_rlc_entity_um_delete; + ret->common.available_tx_space = nr_rlc_entity_um_available_tx_space; ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu_data = deliver_sdu_data; @@ -158,14 +160,15 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm( ret->tx_maxsize = tx_maxsize; - ret->common.recv_pdu = nr_rlc_entity_tm_recv_pdu; - ret->common.buffer_status = nr_rlc_entity_tm_buffer_status; - ret->common.generate_pdu = nr_rlc_entity_tm_generate_pdu; - ret->common.recv_sdu = nr_rlc_entity_tm_recv_sdu; - ret->common.set_time = nr_rlc_entity_tm_set_time; - ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu; - ret->common.reestablishment = nr_rlc_entity_tm_reestablishment; - ret->common.delete = nr_rlc_entity_tm_delete; + ret->common.recv_pdu = nr_rlc_entity_tm_recv_pdu; + ret->common.buffer_status = nr_rlc_entity_tm_buffer_status; + ret->common.generate_pdu = nr_rlc_entity_tm_generate_pdu; + ret->common.recv_sdu = nr_rlc_entity_tm_recv_sdu; + ret->common.set_time = nr_rlc_entity_tm_set_time; + ret->common.discard_sdu = nr_rlc_entity_tm_discard_sdu; + ret->common.reestablishment = nr_rlc_entity_tm_reestablishment; + ret->common.delete = nr_rlc_entity_tm_delete; + ret->common.available_tx_space = nr_rlc_entity_tm_available_tx_space; ret->common.deliver_sdu = deliver_sdu; ret->common.deliver_sdu_data = deliver_sdu_data; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h index b9b638fe0784385c78ced73865ed2148c491ef1a..5cd3bee650835ee66702814655b4eb27e3c3a681 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity.h @@ -50,6 +50,8 @@ typedef struct nr_rlc_entity_t { void (*delete)(struct nr_rlc_entity_t *entity); + int (*available_tx_space)(struct nr_rlc_entity_t *entity); + /* callbacks provided to the RLC module */ void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity, char *buf, int size); diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c index 2382db267fe68283e8ba2c251ec7d49966246daa..91e2bed11ae1705dae6d1cc23aa704c06bf90e52 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -1910,3 +1910,9 @@ void nr_rlc_entity_am_delete(nr_rlc_entity_t *_entity) clear_entity(entity); free(entity); } + +int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity; + return entity->tx_maxsize - entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h index 57ae1a3485698dd7056e87d97b01b51f35ac001d..4c626c4826b68941b80d73107038dbd53f7d638f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.h @@ -99,5 +99,6 @@ void nr_rlc_entity_am_set_time(nr_rlc_entity_t *entity, uint64_t now); void nr_rlc_entity_am_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_am_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_am_delete(nr_rlc_entity_t *entity); +int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *entity); #endif /* _NR_RLC_ENTITY_AM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c index 75408276d18e688491313d3e8fb589fcb754b68d..f85edbba0ff623a14011e8ab8636eecc2b7958fc 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.c @@ -174,3 +174,9 @@ void nr_rlc_entity_tm_delete(nr_rlc_entity_t *_entity) clear_entity(entity); free(entity); } + +int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity; + return entity->tx_maxsize - entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h index 7c8c7e40a01cabb2b013f83469f0e9d91c4ed124..79187037999141f8722be3358298f90383550767 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_tm.h @@ -51,5 +51,6 @@ void nr_rlc_entity_tm_set_time(nr_rlc_entity_t *entity, uint64_t now); void nr_rlc_entity_tm_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_tm_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_tm_delete(nr_rlc_entity_t *entity); +int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *entity); #endif /* _NR_RLC_ENTITY_TM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c index b34a7dc89410f621ca0a3fc68980a7648e13355e..5f2fd592a06672a1b26007d0ae119627114a5eb1 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.c @@ -695,3 +695,9 @@ void nr_rlc_entity_um_delete(nr_rlc_entity_t *_entity) clear_entity(entity); free(entity); } + +int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *_entity) +{ + nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity; + return entity->tx_maxsize - entity->tx_size; +} diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h index 21063a1ea18f08abc2e00d0aedd1f09fc4b86d6a..c40e72ada1da249f718fd3641fd8e830037c21b8 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_um.h @@ -75,5 +75,6 @@ void nr_rlc_entity_um_set_time(nr_rlc_entity_t *entity, uint64_t now); void nr_rlc_entity_um_discard_sdu(nr_rlc_entity_t *_entity, int sdu_id); void nr_rlc_entity_um_reestablishment(nr_rlc_entity_t *_entity); void nr_rlc_entity_um_delete(nr_rlc_entity_t *entity); +int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *entity); #endif /* _NR_RLC_ENTITY_UM_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 7ba08aaa71a5d314dd21de8f0453a80a723155bd..4bd4ea75fd74895afb6e51191188cb7c51be1458 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -101,6 +101,7 @@ void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config switch (rlc_config_pr){ case NR_RLC_Config_PR_um_Bi_Directional: // RLC UM Bi-directional Bearer configuration + LOG_I(RLC, "RLC UM Bi-directional Bearer configuration selected \n"); rlc_Config->choice.um_Bi_Directional = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional)); rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1, sizeof(*rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength)); *rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; @@ -213,10 +214,12 @@ tbs_size_t mac_rlc_data_req( } if (rb != NULL) { + LOG_D(RLC, "MAC PDU to get created for channel_idP:%d \n", channel_idP); rb->set_time(rb, nr_rlc_current_time); maxsize = tb_sizeP; ret = rb->generate_pdu(rb, buffer_pP, maxsize); } else { + LOG_D(RLC, "MAC PDU failed to get created for channel_idP:%d \n", channel_idP); ret = 0; } @@ -394,6 +397,35 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, return RLC_OP_STATUS_OK; } +int nr_rlc_get_available_tx_space( + const rnti_t rntiP, + const logical_chan_id_t channel_idP) +{ + nr_rlc_ue_t *ue; + nr_rlc_entity_t *rb; + int ret; + + nr_rlc_manager_lock(nr_rlc_ue_manager); + ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, rntiP); + + switch (channel_idP) { + case 1 ... 3: rb = ue->srb[channel_idP - 1]; break; + case 4 ... 8: rb = ue->drb[channel_idP - 4]; break; + default: rb = NULL; break; + } + + if (rb != NULL) { + ret = rb->available_tx_space(rb); + } else { + LOG_E(RLC, "[%s] Radio Bearer (channel ID %d) is NULL for UE with rntiP %x\n", __FUNCTION__, channel_idP, rntiP); + ret = -1; + } + + nr_rlc_manager_unlock(nr_rlc_ue_manager); + + return ret; +} + int rlc_module_init(int enb_flag) { static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index 6b3c2281637d00454f7706fa61b562ebcf11abf5..92fbba9bec8071d0c43b25aec631cf1fab62d459 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -46,4 +46,8 @@ void nr_rlc_bearer_init(NR_RLC_BearerConfig_t *RLC_BearerConfig, NR_RLC_BearerCo void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config_pr); -void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig); \ No newline at end of file +void nr_rlc_bearer_init_ul_spec(struct NR_LogicalChannelConfig *mac_LogicalChannelConfig); + +int nr_rlc_get_available_tx_space( + const rnti_t rntiP, + const logical_chan_id_t channel_idP); diff --git a/openair2/LAYER2/nr_rlc/tests/test14.txt.gz b/openair2/LAYER2/nr_rlc/tests/test14.txt.gz index 45e54651eb317c3b7695cfcab7428fe43172227b..53cea67c98d98e91baa4bfcd40518b523ef5a21f 100644 Binary files a/openair2/LAYER2/nr_rlc/tests/test14.txt.gz and b/openair2/LAYER2/nr_rlc/tests/test14.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test15.txt.gz b/openair2/LAYER2/nr_rlc/tests/test15.txt.gz index ddb895d56f0fe88f0ceffb9a100359413292f2b7..61fa01663479944ed13d1c30ee2c3adbe5a70cb1 100644 Binary files a/openair2/LAYER2/nr_rlc/tests/test15.txt.gz and b/openair2/LAYER2/nr_rlc/tests/test15.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test8.txt.gz b/openair2/LAYER2/nr_rlc/tests/test8.txt.gz index c20d43c63b331c2de77e0484922c1b0c1957eb7c..461ae1aebad7294daa7445179da725cbe6e722d0 100644 Binary files a/openair2/LAYER2/nr_rlc/tests/test8.txt.gz and b/openair2/LAYER2/nr_rlc/tests/test8.txt.gz differ diff --git a/openair2/LAYER2/nr_rlc/tests/test9.txt.gz b/openair2/LAYER2/nr_rlc/tests/test9.txt.gz index 27590b7d71c435e04cd19603d90cc0c9c0798597..938fcd6ddcb9a2bcf4bbd2206725a7c35e2a2b79 100644 Binary files a/openair2/LAYER2/nr_rlc/tests/test9.txt.gz and b/openair2/LAYER2/nr_rlc/tests/test9.txt.gz differ diff --git a/openair2/LAYER2/rlc_v2/rlc_oai_api.c b/openair2/LAYER2/rlc_v2/rlc_oai_api.c index 2a6f00c13c49610de35312f286135352603411aa..11ae770e3ecdd8944c56b04713803124ebd41136 100644 --- a/openair2/LAYER2/rlc_v2/rlc_oai_api.c +++ b/openair2/LAYER2/rlc_v2/rlc_oai_api.c @@ -1065,3 +1065,15 @@ void du_rlc_data_req(const protocol_ctxt_t *const ctxt_pP, sdu_sizeP, sdu_pP, NULL, NULL); } + +/* HACK to be removed: nr_rlc_get_available_tx_space is needed by + * openair3/ocp-gtpu/gtp_itf.cpp which is compiled in lte-softmodem + * so let's put a dummy nr_rlc_get_available_tx_space here + */ +int nr_rlc_get_available_tx_space( + const rnti_t rntiP, + const logical_chan_id_t channel_idP) +{ + abort(); + return 0; +} diff --git a/openair2/M2AP/m2ap_common.c b/openair2/M2AP/m2ap_common.c index d288a0a11467b5d3512dd1b6655912b6ced39db0..aa090d124de2400f5e0e6816cfa9db3748c02e1f 100644 --- a/openair2/M2AP/m2ap_common.c +++ b/openair2/M2AP/m2ap_common.c @@ -31,27 +31,6 @@ #include "m2ap_common.h" #include "M2AP_M2AP-PDU.h" -int asn_debug = 0; -int asn1_xer_print = 0; - -#if defined(EMIT_ASN_DEBUG_EXTERN) -inline void ASN_DEBUG(const char *fmt, ...) -{ - if (asn_debug) { - int adi = asn_debug_indent; - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "[ASN1]"); - - while(adi--) fprintf(stderr, " "); - - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - } -} -#endif - ssize_t m2ap_generate_initiating_message( uint8_t **buffer, uint32_t *length, diff --git a/openair2/M2AP/m2ap_common.h b/openair2/M2AP/m2ap_common.h index 95da064b4abdfc1882ade115e9d400a370147d4f..2e84c51938dabc89e8577b5655902aa32d9ecb6d 100644 --- a/openair2/M2AP/m2ap_common.h +++ b/openair2/M2AP/m2ap_common.h @@ -18,10 +18,8 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - -#if HAVE_CONFIG_H_ -# include "config.h" -#endif +#ifndef M2AP_COMMON_H_ +#define M2AP_COMMON_H_ #include "M2AP_ProtocolIE-Field.h" #include "M2AP_M2AP-PDU.h" @@ -38,9 +36,6 @@ #include "common/ran_context.h" -#ifndef M2AP_COMMON_H_ -#define M2AP_COMMON_H_ - /** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation * @ingroup _ref_implementation_ * @{ @@ -55,11 +50,6 @@ # define M2AP_PORT 36423 #endif -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - extern int asn1_xer_print; #if defined(ENB_MODE) diff --git a/openair2/NETWORK_DRIVER/MESH/device.c b/openair2/NETWORK_DRIVER/MESH/device.c index f63408259c88dce75fa338b4820d86cd2c74ee4e..d86e32e56189c4f8f8767bac58bace8d9023c966 100644 --- a/openair2/NETWORK_DRIVER/MESH/device.c +++ b/openair2/NETWORK_DRIVER/MESH/device.c @@ -198,7 +198,8 @@ int nas_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) // End debug information netif_stop_queue(dev); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE>=1796) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \ + || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403) netif_trans_update(dev); #else dev->trans_start = jiffies; @@ -267,7 +268,8 @@ void nas_tx_timeout(struct net_device *dev) printk("TX_TIMEOUT: begin\n"); // (struct nas_priv *)(dev->priv)->stats.tx_errors++; (priv->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE>=1796) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \ + || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403) netif_trans_update(dev); #else dev->trans_start = jiffies; @@ -285,7 +287,8 @@ static const struct net_device_ops nasmesh_netdev_ops = { .ndo_set_mac_address = NULL, .ndo_set_config = nas_set_config, .ndo_do_ioctl = nas_CTL_ioctl, -#if (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE>=1797 && LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0)) +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3,11,0) \ + || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1797 && RHEL_RELEASE_CODE != 2403) .extended.ndo_change_mtu = nas_change_mtu, #else .ndo_change_mtu = nas_change_mtu, diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index 0ff9a73925789f7f26be0f0e6a6e5226a10bf305..bf858a0005db261f9aace3bbf014c6f44ea744f8 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -239,7 +239,8 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) { // End debug information netif_stop_queue(dev_pP); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \ + || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403) netif_trans_update(dev_pP); #else dev_pP->trans_start = jiffies; @@ -315,7 +316,8 @@ void ue_ip_tx_timeout(struct net_device *dev_pP) printk("[UE_IP_DRV][%s] begin\n", __FUNCTION__); // (ue_ip_priv_t *)(dev_pP->priv_p)->stats.tx_errors++; (priv_p->stats).tx_errors++; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0) \ + || (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1796 && RHEL_RELEASE_CODE != 2403) netif_trans_update(dev_pP); #else dev_pP->trans_start = jiffies; @@ -333,7 +335,7 @@ static const struct net_device_ops ue_ip_netdev_ops = { .ndo_set_mac_address = ue_ip_set_mac_address, .ndo_set_config = ue_ip_set_config, .ndo_do_ioctl = NULL, -#if (defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1797) +#if defined RHEL_RELEASE_CODE && RHEL_RELEASE_CODE >= 1797 && RHEL_RELEASE_CODE != 2403 .extended.ndo_change_mtu = ue_ip_change_mtu, #else .ndo_change_mtu = ue_ip_change_mtu, diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index ac0e48a91073db86c74f50a7eb22378e53b5d090..47705082d1c0b12fdd28a2321c401c9a8d43e322 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -215,6 +215,41 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info) UL_info->crc_ind.number_crcs = 0; } +void handle_nr_srs(NR_UL_IND_t *UL_info) { + + if(NFAPI_MODE == NFAPI_MODE_PNF) { + if (UL_info->srs_ind.number_of_pdus > 0) { + LOG_D(PHY,"PNF Sending UL_info->srs_ind.number_of_pdus: %d, SFN/SF:%d.%d \n", + UL_info->srs_ind.number_of_pdus, UL_info->frame, UL_info->slot); + oai_nfapi_nr_srs_indication(&UL_info->srs_ind); + UL_info->srs_ind.number_of_pdus = 0; + } + return; + } + + const module_id_t module_id = UL_info->module_id; + const frame_t frame = UL_info->srs_ind.sfn; + const sub_frame_t slot = UL_info->srs_ind.slot; + const int num_srs = UL_info->srs_ind.number_of_pdus; + const nfapi_nr_srs_indication_pdu_t *srs_list = UL_info->srs_ind.pdu_list; + + for (int i = 0; i < num_srs; i++) { + const nfapi_nr_srs_indication_pdu_t *srs_ind = &srs_list[i]; + LOG_D(NR_PHY, "(%d.%d) UL_info->srs_ind.pdu_list[%d].rnti: 0x%04x\n", frame, slot, i, srs_ind->rnti); + handle_nr_srs_measurements(module_id, + frame, + slot, + srs_ind->rnti, + srs_ind->timing_advance, + srs_ind->num_symbols, + srs_ind->wide_band_snr, + srs_ind->num_reported_symbols, + srs_ind->reported_symbol_list); + } + + UL_info->srs_ind.number_of_pdus = 0; +} + static void free_unqueued_nfapi_indications(nfapi_nr_rach_indication_t *rach_ind, nfapi_nr_uci_indication_t *uci_ind, nfapi_nr_rx_data_indication_t *rx_ind, @@ -431,6 +466,7 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { // clear UL DCI prior to handling ULSCH mac->UL_dci_req[CC_id].numPdus = 0; handle_nr_ulsch(UL_info); + handle_nr_srs(UL_info); if (get_softmodem_params()->emulate_l1) { free_unqueued_nfapi_indications(rach_ind, uci_ind, rx_ind, crc_ind); diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index b8b79f8399f10a5908f5b558aeea52e300a0c7ac..cefafcba80fb6683ce6e832e5f7a062bdfd1552c 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -66,17 +66,6 @@ queue_t nr_tx_req_queue; queue_t nr_ul_dci_req_queue; queue_t nr_ul_tti_req_queue; -static slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT]; - -//static int get_mcs_from_sinr(float sinr); -//static int get_cqi_from_mcs(void); -static void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int sf, int index); -//static bool did_drop_transport_block(int slot, uint16_t rnti); -static float get_bler_val(uint8_t mcs, int sinr); -static bool should_drop_transport_block(int slot, uint16_t rnti); -static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request); -static inline bool is_channel_modeling(void); - void nrue_init_standalone_socket(int tx_port, int rx_port) { { @@ -939,7 +928,7 @@ static void enqueue_nr_nfapi_msg(void *buffer, ssize_t len, nfapi_p7_message_hea return; } -static void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request) +void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request) { int count_sent = 0; NR_UE_MAC_INST_t *mac = get_mac_inst(0); @@ -1114,6 +1103,10 @@ int8_t handle_dlsch(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *u return 0; } +int8_t handle_csirs_measurements(module_id_t module_id, frame_t frame, int slot, fapi_nr_csirs_measurements_t *csirs_measurements) { + return nr_ue_process_csirs_measurements(module_id, frame, slot, csirs_measurements); +} + void update_harq_status(module_id_t module_id, uint8_t harq_pid, uint8_t ack_nack) { NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); @@ -1239,7 +1232,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_length, (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_start_subcarrier, (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.cell_id)) << FAPI_NR_RX_PDU_TYPE_SSB; - free((dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu); + free((dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu); break; case FAPI_NR_RX_PDU_TYPE_SIB: ret_mask |= (handle_bcch_dlsch(dl_info->module_id, @@ -1254,6 +1247,12 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ case FAPI_NR_RX_PDU_TYPE_RAR: ret_mask |= (handle_dlsch(dl_info, ul_time_alignment, i)) << FAPI_NR_RX_PDU_TYPE_RAR; break; + case FAPI_NR_CSIRS_IND: + ret_mask |= (handle_csirs_measurements(dl_info->module_id, + dl_info->frame, + dl_info->slot, + &(dl_info->rx_ind->rx_indication_body+i)->csirs_measurements)) << FAPI_NR_CSIRS_IND; + break; default: break; } @@ -1343,245 +1342,3 @@ void RCconfig_nr_ue_L1(void) { } } } - -/* -static int get_mcs_from_sinr(float sinr) -{ - if (sinr < (nr_bler_data[0].bler_table[0][0])) - { - LOG_D(NR_MAC, "The SINR found is smaller than first MCS table\n"); - return 0; - } - - if (sinr > (nr_bler_data[NR_NUM_MCS-1].bler_table[nr_bler_data[NR_NUM_MCS-1].length - 1][0])) - { - LOG_D(NR_MAC, "The SINR found is larger than last MCS table\n"); - return NR_NUM_MCS-1; - } - - for (int n = NR_NUM_MCS-1; n >= 0; n--) - { - CHECK_INDEX(nr_bler_data, n); - float largest_sinr = (nr_bler_data[n].bler_table[nr_bler_data[n].length - 1][0]); - float smallest_sinr = (nr_bler_data[n].bler_table[0][0]); - if (sinr < largest_sinr && sinr > smallest_sinr) - { - LOG_D(NR_MAC, "The SINR found in MCS %d table\n", n); - return n; - } - } - LOG_E(NR_MAC, "Unable to get an MCS value.\n"); - abort(); -} -*/ - -/* -static int get_cqi_from_mcs(void) -{ - static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15}; - assert(NUM_ELEMENTS(mcs_to_cqi) == NR_NUM_MCS); - int slot = 0; - while (slot < NUM_NFAPI_SLOT) - { - if (slot_rnti_mcs[slot].latest) - { - int num_pdus = slot_rnti_mcs[slot].num_pdus; - if (num_pdus <= 0) - { - LOG_E(NR_MAC, "%s: slot_rnti_mcs[%d].num_pdus = 0\n", __FUNCTION__, slot); - abort(); - } - - CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus); - int mcs = get_mcs_from_sinr(slot_rnti_mcs[slot].sinr); - CHECK_INDEX(mcs_to_cqi, mcs); - int cqi = mcs_to_cqi[mcs]; - LOG_D(NR_MAC, "SINR: %f -> MCS: %d -> CQI: %d\n", slot_rnti_mcs[slot].sinr, mcs, cqi); - return cqi; - } - slot++; - } - LOG_E(NR_MAC, "Unable to get CQI value because no MCS found\n"); - abort(); -} -*/ - -static void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index) -{ - if (pdu == NULL) - { - LOG_E(NR_MAC,"PDU NULL\n"); - abort(); - } - - /* This function is executed for every pdsch pdu type in a dl_tti_request. We save - the assocaited MCS and RNTI value for each. The 'index' passed in is a count of - how many times we have called this function for a particular dl_tti_request. It - allows us to save MCS/RNTI data in correct indicies when multiple pdsch pdu's are received.*/ - for (int i = 0; i < NUM_NFAPI_SLOT; i++) - { - slot_rnti_mcs[i].latest = false; - } - - CHECK_INDEX(slot_rnti_mcs[slot].rnti, index); - CHECK_INDEX(slot_rnti_mcs[slot].mcs, index); - CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, index); - slot_rnti_mcs[slot].rnti[index] = pdu->rnti; - slot_rnti_mcs[slot].mcs[index] = pdu->mcsIndex[0]; - slot_rnti_mcs[slot].rvIndex[index] = pdu->rvIndex[0]; - slot_rnti_mcs[slot].drop_flag[index] = false; - slot_rnti_mcs[slot].num_pdus = index+1; //index starts at 0 so we incrament to get num of pdus - slot_rnti_mcs[slot].latest = true; - LOG_D(NR_MAC, "Adding MCS %d and RNTI %x for slot_rnti_mcs[%d]\n", slot_rnti_mcs[slot].mcs[index], slot_rnti_mcs[slot].rnti[index], slot); - - return; -} - -/* -static bool did_drop_transport_block(int slot, uint16_t rnti) -{ - int num_pdus = slot_rnti_mcs[slot].num_pdus; - if (num_pdus <= 0) - { - LOG_E(MAC, "Problem, the PDU size is <= 0. We dropped this packet\n"); - return true; - } - CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus); - CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus); - for (int n = 0; n < num_pdus; n++) - { - if (slot_rnti_mcs[slot].rnti[n] == rnti && slot_rnti_mcs[slot].drop_flag[n]) - { - return true; - } - } - return false; -} -*/ - -static float get_bler_val(uint8_t mcs, int sinr) -{ - // 4th col = dropped packets, 5th col = total packets - float bler_val = 0.0; - CHECK_INDEX(nr_bler_data, mcs); - LOG_D(NR_MAC, "sinr %d min %d max %d\n", sinr, - (int)(nr_bler_data[mcs].bler_table[0][0] * 10), - (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10) - ); - - if (sinr < (int)(nr_bler_data[mcs].bler_table[0][0] * 10)) - { - LOG_D(NR_MAC, "MCS %d table. SINR is smaller than lowest SINR, bler_val is set based on lowest SINR in table\n", mcs); - bler_val = nr_bler_data[mcs].bler_table[0][4] / nr_bler_data[mcs].bler_table[0][5]; - return bler_val; - } - if (sinr > (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10)) - { - LOG_D(NR_MAC, "MCS %d table. SINR is greater than largest SINR. bler_val is set based on largest SINR in table\n", mcs); - bler_val = nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][4] / nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][5]; - return bler_val; - } - // Loop through bler table to find sinr_index - for (int i = 0; i < nr_bler_data[mcs].length; i++) - { - int temp_sinr = (int)(nr_bler_data[mcs].bler_table[i][0] * 10); - if (temp_sinr == sinr) - { - bler_val = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5]; - return bler_val; - } - // Linear interpolation when SINR is between indices - if (temp_sinr > sinr) - { - float bler_val1 = nr_bler_data[mcs].bler_table[i - 1][4] / nr_bler_data[mcs].bler_table[i - 1][5]; - float bler_val2 = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5]; - LOG_D(NR_MAC, "sinr %d min %f max %f\n", sinr, bler_val1, bler_val2); - return ((bler_val1 + bler_val2) / 2); - } - } - LOG_E(NR_MAC, "NO SINR INDEX FOUND!\n"); - abort(); - -} - -static inline bool is_channel_modeling(void) -{ - /* TODO: For now we enable channel modeling based on the node_number. - Replace with a command line option to enable/disable channel modeling. - The LTE UE will crash when channel modeling is conducted for NSA - mode. It does not crash for LTE mode. We have not implemented channel - modeling for NSA mode yet. For now, we ensure only do do channel modeling - in LTE/NR mode. */ - return get_softmodem_params()->node_number == 0 && !get_softmodem_params()->nsa; -} - -static bool should_drop_transport_block(int slot, uint16_t rnti) -{ - if (!is_channel_modeling()) - { - return false; - } - - /* We want to avoid dropping setup messages because this would be pathological. */ - NR_UE_MAC_INST_t *mac = get_mac_inst(0); - if (mac->ra.ra_state < RA_SUCCEEDED) - { - LOG_D(NR_MAC, "Not dropping because MAC state: %d", mac->ra.ra_state); - return false; - } - - /* Get block error rate (bler_val) from table based on every saved - MCS and SINR to be used as the cutoff rate for dropping packets. - Generate random uniform vairable to compare against bler_val. */ - int num_pdus = slot_rnti_mcs[slot].num_pdus; - assert(slot < 20 && slot >= 0); - LOG_D(NR_MAC, "rnti: %x num_pdus %d state %d slot %u sinr %f\n", - rnti, num_pdus, mac->ra.ra_state, slot, slot_rnti_mcs[slot].sinr); - assert(num_pdus > 0); - CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus); - CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus); - CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus); - int n = 0; - uint8_t mcs = 99; - for (n = 0; n < num_pdus; n++) - { - if (slot_rnti_mcs[slot].rnti[n] == rnti) - { - mcs = slot_rnti_mcs[slot].mcs[n]; - } - if (mcs != 99) - { - /* Use MCS to get the bler value. Since there can be multiple MCS - values for a particular slot, we verify that all PDUs are not - flagged for drop before returning. If even one is flagged for drop - we return immediately because we drop the entire packet. */ - - LOG_D(NR_MAC, "rnti: %x mcs %u slot %u sinr %f\n", - slot_rnti_mcs[slot].rnti[n], mcs, slot, slot_rnti_mcs[slot].sinr); - - float bler_val; - if (slot_rnti_mcs[slot].rvIndex[n] != 0) - bler_val = 0; - else - bler_val = get_bler_val(mcs, ((int)(slot_rnti_mcs[slot].sinr * 10))); - double drop_cutoff = ((double) rand() / (RAND_MAX)); - assert(drop_cutoff <= 1); - LOG_D(NR_MAC, "SINR = %f, Bler_val = %f, MCS = %"PRIu8"\n", slot_rnti_mcs[slot].sinr, bler_val, slot_rnti_mcs[slot].mcs[n]); - if (drop_cutoff <= bler_val) - { - slot_rnti_mcs[slot].drop_flag[n] = true; - LOG_T(NR_MAC, "We are dropping this packet. Bler_val = %f, MCS = %"PRIu8", slot = %d\n", bler_val, slot_rnti_mcs[slot].mcs[n], slot); - return slot_rnti_mcs[slot].drop_flag[n]; - } - } - - } - - if (mcs == 99) - { - LOG_E(NR_MAC, "NO MCS Found for rnti %x. slot_rnti_mcs[%d].mcs[%d] \n", rnti, slot, n); - abort(); - } - return false; -} diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 45d1a071ca96323c353dcf5d0b5754c773fedae2..f663c17d10f310530483b65dfa506811b7cb3037 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -40,45 +40,12 @@ #include "openair2/PHY_INTERFACE/queue_t.h" #include "nfapi_nr_interface_scf.h" #include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" +#include "NR_Packet_Drop.h" -#define NR_NUM_MCS 29 -#define NUM_SINR 100 -#define NUM_BLER_COL 13 -#define NUM_NFAPI_SLOT 20 -#define NR_NUM_LAYER 1 +extern slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT]; typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t; -typedef struct nr_phy_channel_params_t -{ - uint16_t sfn_slot; - uint16_t message_id; - uint16_t nb_of_sinrs; - float sinr[NR_NUM_LAYER]; - // Incomplete, need all channel parameters -} nr_phy_channel_params_t; - -typedef struct -{ - uint8_t slot; - uint16_t rnti[256]; - uint8_t mcs[256]; - uint8_t rvIndex[256]; - float sinr; - uint16_t num_pdus; - bool drop_flag[256]; - bool latest; - -} slot_rnti_mcs_s; - -typedef struct -{ - uint16_t length; - float bler_table[NUM_SINR][NUM_BLER_COL]; -} nr_bler_struct; - -extern nr_bler_struct nr_bler_data[NR_NUM_MCS]; - typedef enum { ONLY_PUSCH, NOT_PUSCH, diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c new file mode 100644 index 0000000000000000000000000000000000000000..97938c6b0272f8ef231bbb5a2c9101fefb18281f --- /dev/null +++ b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.c @@ -0,0 +1,183 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +#include <stdio.h> +#include "openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h" +#include "executables/softmodem-common.h" +#include "NR_MAC_UE/mac_proto.h" + +slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT]; +void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int slot, int index) +{ + if (pdu == NULL) + { + LOG_E(NR_MAC,"PDU NULL\n"); + abort(); + } + + /* This function is executed for every pdsch pdu type in a dl_tti_request. We save + the assocaited MCS and RNTI value for each. The 'index' passed in is a count of + how many times we have called this function for a particular dl_tti_request. It + allows us to save MCS/RNTI data in correct indicies when multiple pdsch pdu's are received.*/ + for (int i = 0; i < NUM_NFAPI_SLOT; i++) + { + slot_rnti_mcs[i].latest = false; + } + + CHECK_INDEX(slot_rnti_mcs[slot].rnti, index); + CHECK_INDEX(slot_rnti_mcs[slot].mcs, index); + CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, index); + slot_rnti_mcs[slot].rnti[index] = pdu->rnti; + slot_rnti_mcs[slot].mcs[index] = pdu->mcsIndex[0]; + slot_rnti_mcs[slot].rvIndex[index] = pdu->rvIndex[0]; + slot_rnti_mcs[slot].drop_flag[index] = false; + slot_rnti_mcs[slot].num_pdus = index+1; //index starts at 0 so we incrament to get num of pdus + slot_rnti_mcs[slot].latest = true; + LOG_D(NR_MAC, "Adding MCS %d and RNTI %x for slot_rnti_mcs[%d]\n", slot_rnti_mcs[slot].mcs[index], slot_rnti_mcs[slot].rnti[index], slot); + + return; +} + +extern nr_bler_struct nr_bler_data[NR_NUM_MCS]; +float get_bler_val(uint8_t mcs, int sinr) +{ + // 4th col = dropped packets, 5th col = total packets + float bler_val = 0.0; + CHECK_INDEX(nr_bler_data, mcs); + LOG_D(NR_MAC, "sinr %d min %d max %d\n", sinr, + (int)(nr_bler_data[mcs].bler_table[0][0] * 10), + (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10) + ); + + if (sinr < (int)(nr_bler_data[mcs].bler_table[0][0] * 10)) + { + LOG_D(NR_MAC, "MCS %d table. SINR is smaller than lowest SINR, bler_val is set based on lowest SINR in table\n", mcs); + bler_val = nr_bler_data[mcs].bler_table[0][4] / nr_bler_data[mcs].bler_table[0][5]; + return bler_val; + } + if (sinr > (int)(nr_bler_data[mcs].bler_table[nr_bler_data[mcs].length - 1][0] * 10)) + { + LOG_D(NR_MAC, "MCS %d table. SINR is greater than largest SINR. bler_val is set based on largest SINR in table\n", mcs); + bler_val = nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][4] / nr_bler_data[mcs].bler_table[(nr_bler_data[mcs].length - 1)][5]; + return bler_val; + } + // Loop through bler table to find sinr_index + for (int i = 0; i < nr_bler_data[mcs].length; i++) + { + int temp_sinr = (int)(nr_bler_data[mcs].bler_table[i][0] * 10); + if (temp_sinr == sinr) + { + bler_val = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5]; + return bler_val; + } + // Linear interpolation when SINR is between indices + if (temp_sinr > sinr) + { + float bler_val1 = nr_bler_data[mcs].bler_table[i - 1][4] / nr_bler_data[mcs].bler_table[i - 1][5]; + float bler_val2 = nr_bler_data[mcs].bler_table[i][4] / nr_bler_data[mcs].bler_table[i][5]; + LOG_D(NR_MAC, "sinr %d min %f max %f\n", sinr, bler_val1, bler_val2); + return ((bler_val1 + bler_val2) / 2); + } + } + LOG_E(NR_MAC, "NO SINR INDEX FOUND!\n"); + abort(); + +} + +bool is_channel_modeling(void) +{ + /* TODO: For now we enable channel modeling based on the node_number. + Replace with a command line option to enable/disable channel modeling. + The LTE UE will crash when channel modeling is conducted for NSA + mode. It does not crash for LTE mode. We have not implemented channel + modeling for NSA mode yet. For now, we ensure only do do channel modeling + in LTE/NR mode. */ + return get_softmodem_params()->node_number == 0 && !get_softmodem_params()->nsa; +} + +bool should_drop_transport_block(int slot, uint16_t rnti) +{ + if (!is_channel_modeling()) + { + return false; + } + + /* We want to avoid dropping setup messages because this would be pathological. */ + NR_UE_MAC_INST_t *mac = get_mac_inst(0); + if (mac->ra.ra_state < RA_SUCCEEDED) + { + LOG_D(NR_MAC, "Not dropping because MAC state: %d", mac->ra.ra_state); + return false; + } + + /* Get block error rate (bler_val) from table based on every saved + MCS and SINR to be used as the cutoff rate for dropping packets. + Generate random uniform vairable to compare against bler_val. */ + int num_pdus = slot_rnti_mcs[slot].num_pdus; + assert(slot < 20 && slot >= 0); + LOG_D(NR_MAC, "rnti: %x num_pdus %d state %d slot %u sinr %f\n", + rnti, num_pdus, mac->ra.ra_state, slot, slot_rnti_mcs[slot].sinr); + assert(num_pdus > 0); + CHECK_INDEX(slot_rnti_mcs[slot].rnti, num_pdus); + CHECK_INDEX(slot_rnti_mcs[slot].mcs, num_pdus); + CHECK_INDEX(slot_rnti_mcs[slot].drop_flag, num_pdus); + int n = 0; + uint8_t mcs = 99; + for (n = 0; n < num_pdus; n++) + { + if (slot_rnti_mcs[slot].rnti[n] == rnti) + { + mcs = slot_rnti_mcs[slot].mcs[n]; + } + if (mcs != 99) + { + /* Use MCS to get the bler value. Since there can be multiple MCS + values for a particular slot, we verify that all PDUs are not + flagged for drop before returning. If even one is flagged for drop + we return immediately because we drop the entire packet. */ + + LOG_D(NR_MAC, "rnti: %x mcs %u slot %u sinr %f\n", + slot_rnti_mcs[slot].rnti[n], mcs, slot, slot_rnti_mcs[slot].sinr); + + float bler_val; + if (slot_rnti_mcs[slot].rvIndex[n] != 0) + bler_val = 0; + else + bler_val = get_bler_val(mcs, ((int)(slot_rnti_mcs[slot].sinr * 10))); + double drop_cutoff = ((double) rand() / (RAND_MAX)); + assert(drop_cutoff <= 1); + LOG_D(NR_MAC, "SINR = %f, Bler_val = %f, MCS = %"PRIu8"\n", slot_rnti_mcs[slot].sinr, bler_val, slot_rnti_mcs[slot].mcs[n]); + if (drop_cutoff <= bler_val) + { + slot_rnti_mcs[slot].drop_flag[n] = true; + LOG_T(NR_MAC, "We are dropping this packet. Bler_val = %f, MCS = %"PRIu8", slot = %d\n", bler_val, slot_rnti_mcs[slot].mcs[n], slot); + return slot_rnti_mcs[slot].drop_flag[n]; + } + } + + } + + if (mcs == 99) + { + LOG_E(NR_MAC, "NO MCS Found for rnti %x. slot_rnti_mcs[%d].mcs[%d] \n", rnti, slot, n); + abort(); + } + return false; +} diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h new file mode 100644 index 0000000000000000000000000000000000000000..549eb5c2e38288be8f69bc01ddf34c5d31843256 --- /dev/null +++ b/openair2/NR_UE_PHY_INTERFACE/NR_Packet_Drop.h @@ -0,0 +1,68 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ +#ifndef __NR_CHAN_MODEL_H__ +#define __NR_CHAN_MODEL_H__ + +#include <platform_types.h> +#include <nfapi_nr_interface_scf.h> +#include <openair1/PHY/thread_NR_UE.h> +#include "openair2/NR_PHY_INTERFACE/NR_IF_Module.h" + +#define NR_NUM_MCS 29 +#define NUM_SINR 100 +#define NUM_BLER_COL 13 +#define NUM_NFAPI_SLOT 20 +#define NR_NUM_LAYER 1 +#define MAX_CHAN_PARAMS 256 + +typedef struct nr_phy_channel_params_t +{ + uint16_t sfn_slot; + uint16_t message_id; + uint16_t nb_of_sinrs; + float sinr[NR_NUM_LAYER]; +} nr_phy_channel_params_t; + +typedef struct +{ + uint8_t slot; + uint16_t rnti[MAX_CHAN_PARAMS]; + uint8_t mcs[MAX_CHAN_PARAMS]; + uint8_t rvIndex[MAX_CHAN_PARAMS]; + float sinr; + uint16_t num_pdus; + bool drop_flag[MAX_CHAN_PARAMS]; + bool latest; +} slot_rnti_mcs_s; + +typedef struct +{ + uint16_t length; + float bler_table[NUM_SINR][NUM_BLER_COL]; +} nr_bler_struct; + +void read_channel_param(const nfapi_nr_dl_tti_pdsch_pdu_rel15_t * pdu, int sf, int index); +void save_pdsch_pdu_for_crnti(nfapi_nr_dl_tti_request_t *dl_tti_request); +float get_bler_val(uint8_t mcs, int sinr); +bool should_drop_transport_block(int slot, uint16_t rnti); +bool is_channel_modeling(void); + +#endif diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index c4650f18f3a93e8c7e1878bbc5e687b6b0da81b2..cd57ea9ff101ea225e6169408cc5e5fad5d3d255 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -1956,7 +1956,7 @@ static int get_mcs_from_sinr(float sinr) static int get_cqi_from_mcs(void) { - static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15}; + static const int mcs_to_cqi[] = {0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15}; assert(NUM_ELEMENTS(mcs_to_cqi) == NUM_MCS); int sf = 0; while(sf < NUM_NFAPI_SUBFRAME) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h index d68d1dffdd91a25371c7193521bd2ae68f8a3298..fe0e7be12e171a12c9858bdbf38cd6dfaf94b9f9 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.h +++ b/openair2/PHY_INTERFACE/phy_stub_UE.h @@ -21,7 +21,7 @@ //#include "openair1/PHY/LTE_TRANSPORT/defs.h" #include "queue_t.h" -#define NUM_MCS 28 +#define NUM_MCS 29 #define NUM_SINR 100 #define NUM_BLER_COL 13 #define LTE_NUM_LAYER 1 diff --git a/openair2/RRC/LITE/rrc_common.c b/openair2/RRC/LITE/rrc_common.c index a4239e857d97acc5e9b41ea07599c93f1e94f691..f0c4e94c9990b5af3f631110ec21f5ab88bd951d 100644 --- a/openair2/RRC/LITE/rrc_common.c +++ b/openair2/RRC/LITE/rrc_common.c @@ -306,7 +306,7 @@ rrc_rx_tx( LOG_D(RRC,"SFN.SN %d.%d => release timer %d/%d\n",ctxt_pP->frame,ctxt_pP->subframe, ue_context_p->ue_context.ue_release_timer,ue_context_p->ue_context.ue_release_timer_thres); if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) { - if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == true) { LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/20000\n", ue_context_p->ue_context.rnti, ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index 0a63acc8fb8882ded746feaa3316a3b626859503..c12d2aa873e3e55e2160037f9ce5f28a9a922410 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -299,7 +299,7 @@ mac_rrc_data_ind( const uint8_t *sduP, const sdu_size_t sdu_lenP, const uint8_t mbsfn_sync_areaP, - const boolean_t brOption + const bool brOption ) //-------------------------------------------------------------------------- { diff --git a/openair2/RRC/LTE/L2_interface_common.c b/openair2/RRC/LTE/L2_interface_common.c index 1993fe7de0973278c63cde20d1f247a174371f9b..660bd91dda8d99d05a8051f0a22724d71fed188a 100644 --- a/openair2/RRC/LTE/L2_interface_common.c +++ b/openair2/RRC/LTE/L2_interface_common.c @@ -58,7 +58,7 @@ rrc_data_req( { if(sdu_sizeP == 255) { LOG_I(RRC,"sdu_sizeP == 255"); - return FALSE; + return false; } MessageDef *message_p; @@ -94,7 +94,7 @@ rrc_data_req( if (ctxt_pP->enb_flag && NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) pdcp_run(ctxt_pP); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } //------------------------------------------------------------------------------ diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index 534030864a295a2a59c95366ae448a0d66e5363f..850ecf1b588132179bf79ad30b97bfe708b26bd4 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -298,7 +298,7 @@ rrc_data_req_ue( TASK_PDCP_UE, ctxt_pP->instance, message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index c34c65b19503fca2515d973575fa97316e062756..e5024e35055a289e9a09c87bddb1383f0508557f 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -343,7 +343,7 @@ uint8_t do_MIB_SL(const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, if (in_coverage > 0 ) { //in coverage - mib_sl->inCoverage_r12 = TRUE; + mib_sl->inCoverage_r12 = true; mib_sl->sl_Bandwidth_r12 = *UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_Bandwidth; if (UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config) { @@ -366,7 +366,7 @@ uint8_t do_MIB_SL(const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, } else { //Todo - out of coverage for V2X // Todo - UE has a selected SyncRef UE - mib_sl->inCoverage_r12 = FALSE; + mib_sl->inCoverage_r12 = false; //set sl-Bandwidth, subframeAssignmentSL and reserved from the pre-configured parameters } @@ -989,7 +989,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, sib1_1250->nonCriticalExtension = NULL; ////Rel1310 if ((configuration->schedulingInfoSIB1_BR_r13[CC_id] != 0) && - (brOption==TRUE)) { + (brOption==true)) { sib1_1250->nonCriticalExtension = calloc(1, sizeof(LTE_SystemInformationBlockType1_v1310_IEs_t)); memset(sib1_1250->nonCriticalExtension, 0, sizeof(LTE_SystemInformationBlockType1_v1310_IEs_t)); LTE_SystemInformationBlockType1_v1310_IEs_t *sib1_1310 = sib1_1250->nonCriticalExtension; @@ -1279,7 +1279,7 @@ uint8_t do_SIB23(uint8_t Mod_id, *sib2 = &sib2_part->choice.sib2; *sib3 = &sib3_part->choice.sib3; - if ((configuration->eMBMS_configured > 0) && (brOption==FALSE)) { + if ((configuration->eMBMS_configured > 0) && (brOption==false)) { sib13_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); memset(sib13_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); sib13_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920; @@ -2781,7 +2781,7 @@ do_RRCConnectionSetup( mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; // max number of UL HARQ transmission mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; // LTE_RetxBSR_Timer_r12_sf5120 // regular BSR timer - mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // false //* timeAlignmentTimerDedicated *// mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; //* DRX Config *// @@ -3135,7 +3135,7 @@ uint8_t do_RRCConnectionSetup_BR( //mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; - mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // false mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; mac_MainConfig->drx_Config = NULL; mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); diff --git a/openair2/RRC/LTE/defs_NB_IoT.h b/openair2/RRC/LTE/defs_NB_IoT.h index c76bdea53f228cecba6c1ebb807498b893148a19..17ef77ff1726a6b55ba56f8631b4bca371a826b5 100644 --- a/openair2/RRC/LTE/defs_NB_IoT.h +++ b/openair2/RRC/LTE/defs_NB_IoT.h @@ -37,9 +37,6 @@ #include "COMMON/s1ap_messages_types.h" #include "COMMON/rrc_messages_types.h" -#if ITTI_SIM -#include "COMMON/itti_sim_messages_types.h" -#endif #include "collection/tree.h" #include "rrc_types_NB_IoT.h" @@ -156,7 +153,7 @@ typedef struct UE_RRC_INFO_NB_IoT_s { #define RRC_TRANSACTION_IDENTIFIER_NUMBER 3 typedef struct UE_S_TMSI_NB_IoT_s { - boolean_t presence; + bool presence; mme_code_t mme_code; m_tmsi_t m_tmsi; } __attribute__ ((__packed__)) UE_S_TMSI_NB_IoT; diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 9b37853ed2b2ac5503f29632e66e9f88cf3bbf99..577ee3effdf3dc90d3ee696958d451d4f9e74d79 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -4351,8 +4351,8 @@ void rrc_ue_generate_nrMeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t AssertFatal(size >= 0, "do_nrMeasurementReport failed \n"); LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index); - int result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA,NULL, NULL); - AssertFatal (result == TRUE, "PDCP data request failed!\n"); + const bool result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA,NULL, NULL); + AssertFatal (result == true, "PDCP data request failed!\n"); } } } @@ -4370,7 +4370,6 @@ void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t e long nElem, nElem1; float rsrp_filtered, rsrq_filtered; static frame_t pframe=0; - int result; nElem = 98; nElem1 = 35; target_eNB_offset = UE_rrc_inst[ctxt_pP->module_id].Info[0].handoverTarget; // eNB_offset of target eNB: used to obtain the mod_id of target eNB @@ -4420,8 +4419,8 @@ void rrc_ue_generate_MeasurementReport(protocol_ctxt_t *const ctxt_pP, uint8_t e AssertFatal(size >= 0, "do_MeasurementReport failed \n"); LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d. Size is %zu\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index, size); - result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA,NULL, NULL); - AssertFatal (result == TRUE, "PDCP data request failed!\n"); + const bool result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA,NULL, NULL); + AssertFatal (result == true, "PDCP data request failed!\n"); //LOG_D(RRC, "[UE %d] Frame %d Sending MeasReport (%d bytes) through DCCH%d to PDCP \n",ue_mod_idP,frameP, size, DCCH); } diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 64baf5e2ace04a3687e2df3a0168bcab3c2d3f8a..f5841b09f88da5ca5af74ad533b8c4b7f27a1f54 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -36,11 +36,11 @@ #include <string.h> #include "collection/tree.h" +#include "collection/linear_alloc.h" #include "common/ngran_types.h" #include "rrc_types.h" //#include "PHY/phy_defs.h" #include "LAYER2/RLC/rlc.h" -#include "RRC/NR/nr_rrc_types.h" #include "NR_UE-MRDC-Capability.h" #include "NR_UE-NR-Capability.h" @@ -219,17 +219,6 @@ void *send_UE_status_notification(void *); #include "commonDef.h" -//-------- -typedef unsigned int uid_t; -#define UID_LINEAR_ALLOCATOR_BITMAP_SIZE (((MAX_MOBILES_PER_ENB/8)/sizeof(unsigned int)) + 1) -typedef struct uid_linear_allocator_s { - unsigned int bitmap[UID_LINEAR_ALLOCATOR_BITMAP_SIZE]; -} uid_allocator_t; - -//-------- - - - #define PROTOCOL_RRC_CTXT_UE_FMT PROTOCOL_CTXT_FMT #define PROTOCOL_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_CTXT_ARGS(CTXT_Pp) @@ -367,7 +356,7 @@ typedef struct UE_RRC_INFO_s { } __attribute__ ((__packed__)) UE_RRC_INFO; typedef struct UE_S_TMSI_s { - boolean_t presence; + bool presence; mme_code_t mme_code; m_tmsi_t m_tmsi; } __attribute__ ((__packed__)) UE_S_TMSI; @@ -668,8 +657,6 @@ typedef struct eNB_RRC_UE_s { int nr_capabilities_requested; } eNB_RRC_UE_t; -typedef uid_t ue_uid_t; - typedef struct rrc_eNB_ue_context_s { /* Tree related data */ RB_ENTRY(rrc_eNB_ue_context_s) entries; @@ -680,7 +667,7 @@ typedef struct rrc_eNB_ue_context_s { rnti_t ue_id_rnti; // another key for protocol layers but should not be used as a key for RB tree - ue_uid_t local_uid; + uid_t local_uid; /* UE id for initial connection to S1AP */ struct eNB_RRC_UE_s ue_context; @@ -762,7 +749,7 @@ typedef struct eNB_RRC_INST_s { char *node_name; uint32_t node_id; rrc_eNB_carrier_data_t carrier[MAX_NUM_CCs]; - uid_allocator_t uid_allocator; // for rrc_ue_head + uid_allocator_t uid_allocator; RB_HEAD(rrc_ue_tree_s, rrc_eNB_ue_context_s) rrc_ue_head; // ue_context tree key search by rnti uint8_t HO_flag; uint8_t Nb_ue; @@ -931,7 +918,7 @@ typedef struct UE_RRC_INST_s { } UE_RRC_INST; typedef struct UE_PF_PO_s { - boolean_t enable_flag; /* flag indicate whether current object is used */ + bool enable_flag; /* flag indicate whether current object is used */ uint16_t ue_index_value; /* UE index value */ uint8_t PF_min; /* minimal value of Paging Frame (PF) */ uint8_t PO; /* Paging Occasion (PO) */ diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index ea98d3169d50f6dcebe186bce87546040a4d9fcd..8be30175e1173b82675f02c44b842ee7da70b3ea 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -150,7 +150,7 @@ init_SI( LTE_SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL; LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); - if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == TRUE) { + if(configuration->radioresourceconfig[CC_id].mbms_dedicated_serving_cell == true) { LOG_A(RRC, "Configuring MIB FeMBMS (N_RB_DL %d)\n", (int)configuration->N_RB_DL[CC_id]); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB_FeMBMS = (uint8_t *) malloc16(4); @@ -266,7 +266,7 @@ init_SI( carrier->sizeof_SIB1 = do_SIB1(&rrc->carrier[CC_id], ctxt_pP->module_id, CC_id, - FALSE, + false, configuration ); AssertFatal(carrier->sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255"); @@ -276,7 +276,7 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1_BR = (uint8_t *) malloc16(32); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1_BR = do_SIB1(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id], ctxt_pP->module_id, - CC_id, TRUE, configuration); + CC_id, true, configuration); } } @@ -285,7 +285,7 @@ init_SI( AssertFatal(carrier->SIB23!=NULL,"cannot allocate memory for SIB"); carrier->sizeof_SIB23 = do_SIB23(ctxt_pP->module_id, CC_id, - FALSE, + false, configuration ); LOG_I(RRC,"do_SIB23, size %d \n ", carrier->sizeof_SIB23); @@ -295,7 +295,7 @@ init_SI( if (configuration->schedulingInfoSIB1_BR_r13[CC_id]>0) { carrier->SIB23_BR = (uint8_t *) malloc16(64); AssertFatal(carrier->SIB23_BR!=NULL,"cannot allocate memory for SIB"); - carrier->sizeof_SIB23_BR = do_SIB23(ctxt_pP->module_id, CC_id, TRUE, configuration); + carrier->sizeof_SIB23_BR = do_SIB23(ctxt_pP->module_id, CC_id, true, configuration); } LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" SIB2/3 Contents (partial)\n", @@ -661,7 +661,7 @@ rrc_eNB_get_next_transaction_identifier( ////----------------------------------------------------------------------------- //{ // -// boolean_t reg = FALSE; +// bool reg = false; // module_id_t i; // // AssertFatal(enb_mod_idP < NB_eNB_INST, "eNB index invalid (%d/%d)!", enb_mod_idP, NB_eNB_INST); @@ -669,12 +669,12 @@ rrc_eNB_get_next_transaction_identifier( // for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { // if (RC.rrc[enb_mod_idP]->Info.UE_info[i] == UE_identity) { // // UE_identity already registered -// reg = TRUE; +// reg = true; // break; // } // } // -// if (reg == FALSE) { +// if (reg == false) { // return (UE_MODULE_INVALID); // } else // return (i); @@ -713,7 +713,7 @@ rrc_eNB_ue_context_stmsi_exist( m_tmsiP, mme_codeP, ue_context_p, ue_context_p->ue_context.rnti); - if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == true) { printf("=> S-TMSI %x, MME %x\n", ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code); @@ -976,28 +976,24 @@ rrc_eNB_free_UE( put_UE_in_freelist(enb_mod_idP, rnti, 1); } -void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti) { +void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, bool removeFlag) { eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; pthread_mutex_lock(&lock_ue_freelist); - UE_free_list_t *free_list = &eNB_MAC->UE_free_list; - free_list->UE_free_ctrl[free_list->head_freelist].rnti = 0; - free_list->head_freelist = (free_list->head_freelist + 1) % (NUMBER_OF_UE_MAX+1); - free_list->num_UEs--; - pthread_mutex_unlock(&lock_ue_freelist); -} - -void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag) { - UE_free_list_t *free_list = NULL; - eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; - pthread_mutex_lock(&lock_ue_freelist); - free_list = &eNB_MAC->UE_free_list; - free_list->UE_free_ctrl[free_list->tail_freelist].rnti = rnti; - free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = removeFlag; - free_list->UE_free_ctrl[free_list->tail_freelist].raFlag = 0; - free_list->num_UEs++; + LOG_I(PHY,"add ue %d in fre list, context flag: %d\n", rnti, removeFlag); + int i; + for (i=0; i < sizeofArray(eNB_MAC->UE_free_ctrl); i++) + if (eNB_MAC->UE_free_ctrl[i].rnti == 0) + break; + if (i==sizeofArray(eNB_MAC->UE_free_ctrl)) { + LOG_E(PHY,"List of UE to free is full\n"); + pthread_mutex_unlock(&lock_ue_freelist); + return; + } + eNB_MAC->UE_free_ctrl[i].rnti = rnti; + eNB_MAC->UE_free_ctrl[i].removeContextFlg = removeFlag; + eNB_MAC->UE_free_ctrl[i].raFlag = 0; eNB_MAC->UE_release_req.ue_release_request_body.ue_release_request_TLVs_list[eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs].rnti = rnti; eNB_MAC->UE_release_req.ue_release_request_body.number_of_TLVs++; - free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1); pthread_mutex_unlock(&lock_ue_freelist); } @@ -1007,104 +1003,47 @@ extern void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); extern void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); void release_UE_in_freeList(module_id_t mod_id) { - int i, j, CC_id, pdu_number; - protocol_ctxt_t ctxt; - nfapi_ul_config_request_body_t *ul_req_tmp = NULL; PHY_VARS_eNB *eNB_PHY = NULL; - struct rrc_eNB_ue_context_s *ue_context_pP = NULL; eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; - boolean_t remove_UEContext; - rnti_t rnti; - int head, tail, ue_num; pthread_mutex_lock(&lock_ue_freelist); - head = eNB_MAC->UE_free_list.head_freelist; - tail = eNB_MAC->UE_free_list.tail_freelist; - if(head == tail) { - pthread_mutex_unlock(&lock_ue_freelist); - return; - } - - if(tail < head) { - tail = head + eNB_MAC->UE_free_list.num_UEs; - } - - pthread_mutex_unlock(&lock_ue_freelist); - - for(ue_num = head; ue_num < tail; ue_num++) { - ue_num = ue_num % (NUMBER_OF_UE_MAX+1); - rnti = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].rnti; + for(int ue_num = 0; ue_num < sizeofArray(eNB_MAC->UE_free_ctrl) ; ue_num++) { + rnti_t rnti = eNB_MAC->UE_free_ctrl[ue_num].rnti; if(rnti != 0) { - remove_UEContext = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].removeContextFlg; + protocol_ctxt_t ctxt; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, rnti, 0, 0,mod_id); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { eNB_PHY = RC.eNB[mod_id][CC_id]; int id; // clean ULSCH entries for rnti - id = find_ulsch(rnti,eNB_PHY,eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST); + id = find_ulsch(rnti,eNB_PHY,eNB_MAC->UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST); if (id>=0) clean_eNb_ulsch(eNB_PHY->ulsch[id]); // clean DLSCH entries for rnti - id = find_dlsch(rnti,eNB_PHY,eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST); + id = find_dlsch(rnti,eNB_PHY,eNB_MAC->UE_free_ctrl[ue_num].raFlag ? SEARCH_EXIST_RA : SEARCH_EXIST); if (id>=0) clean_eNb_dlsch(eNB_PHY->dlsch[id][0]); // clean UCI entries for rnti - for (i=0; i<NUMBER_OF_UCI_MAX; i++) { + for (int i=0; i<NUMBER_OF_UCI_MAX; i++) { if(eNB_PHY->uci_vars[i].rnti == rnti) { LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); } } - /* - for (i=0; i<MAX_MOBILES_PER_ENB; i++) { - ulsch = eNB_PHY->ulsch[i]; - - if((ulsch != NULL) && (ulsch->rnti == rnti)) { - void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); - LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); - clean_eNb_ulsch(ulsch); - } - - dlsch = eNB_PHY->dlsch[i][0]; - - if((dlsch != NULL) && (dlsch->rnti == rnti)) { - void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); - LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti); - clean_eNb_dlsch(dlsch); - } - } - - ulsch = eNB_PHY->ulsch[i]; - - if((ulsch != NULL) && (ulsch->rnti == rnti)) { - void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); - LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); - clean_eNb_ulsch(ulsch); - } - - for (i=0; i<NUMBER_OF_UCI_MAX; i++) { - if(eNB_PHY->uci_vars[i].rnti == rnti) { - LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); - memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); - } - } - */ - if (flexran_agent_get_rrc_xface(mod_id)) { - flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change( - mod_id, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change( mod_id, rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } - for(j = 0; j < 10; j++) { - ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body; + for(int j = 0; j < 10; j++) { + nfapi_ul_config_request_body_t *ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body; if(ul_req_tmp) { - pdu_number = ul_req_tmp->number_of_pdus; + int pdu_number = ul_req_tmp->number_of_pdus; for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--) { if((ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) || @@ -1126,7 +1065,8 @@ void release_UE_in_freeList(module_id_t mod_id) { } if (!NODE_IS_CU(RC.rrc[mod_id]->node_type)) { - rrc_mac_remove_ue(mod_id,rnti); + if (!eNB_MAC->UE_free_ctrl[ue_num].raFlag) + rrc_mac_remove_ue(mod_id,rnti); rrc_rlc_remove_ue(&ctxt); pdcp_remove_UE(&ctxt); } else { @@ -1139,19 +1079,20 @@ void release_UE_in_freeList(module_id_t mod_id) { itti_send_msg_to_task(TASK_CU_F1, mod_id, m); } - if(remove_UEContext) { - ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[mod_id],rnti); - + if(eNB_MAC->UE_free_ctrl[ue_num].removeContextFlg) { + struct rrc_eNB_ue_context_s *ue_context_pP = rrc_eNB_get_ue_context(RC.rrc[mod_id],rnti); if(ue_context_pP) { + LOG_I(PHY, "remove RNTI %04x\n", rnti); rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id], (struct rrc_eNB_ue_context_s *) ue_context_pP); } } - LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList\n", rnti); - remove_UE_from_freelist(mod_id, rnti); + LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList ra context: %d\n", rnti, eNB_MAC->UE_free_ctrl[ue_num].raFlag); + eNB_MAC->UE_free_ctrl[ue_num].rnti = 0; } } + pthread_mutex_unlock(&lock_ue_freelist); } int rrc_eNB_previous_SRB2(rrc_eNB_ue_context_t *ue_context_pP) { @@ -1678,7 +1619,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( ue_context_pP->ue_context.rnti = ctxt_pP->rnti; if (EPC_MODE_ENABLED) { - uint8_t send_security_mode_command = FALSE; + uint8_t send_security_mode_command = false; rrc_pdcp_config_security( ctxt_pP, ue_context_pP, @@ -2332,7 +2273,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *co // PDCP PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; + PDCP_rlc_AM->statusReportRequired = false; break; default : @@ -2590,7 +2531,7 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *cons PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; + PDCP_rlc_AM->statusReportRequired = false; break; default : @@ -2951,7 +2892,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t #ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; + PDCP_rlc_AM->statusReportRequired = false; #else PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; @@ -3347,7 +3288,7 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.present = LTE_ReportConfigInterRAT__triggerType__event__eventId_PR_eventB1_NR_r15; ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.b1_ThresholdNR_r15.present = LTE_ThresholdNR_r15_PR_nr_RSRP_r15; ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.b1_ThresholdNR_r15.choice.nr_RSRP_r15 = 0; - ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.reportOnLeave_r15 = FALSE; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.eventId.choice.eventB1_NR_r15.reportOnLeave_r15 = false; ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.hysteresis = 2; ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.triggerType.choice.event.timeToTrigger = LTE_TimeToTrigger_ms80; ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.maxReportCells = 4; @@ -3361,9 +3302,9 @@ void rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t if (ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15 == NULL) exit(1); - ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrp = TRUE; - ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrq = TRUE; - ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_sinr = TRUE; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrp = true; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_rsrq = true; + ReportConfig_NR->reportConfig.choice.reportConfigInterRAT.ext7->reportQuantityCellNR_r15->ss_sinr = true; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_NR); LOG_A(RRC, "Generating RRCCConnectionReconfigurationRequest (NRUE Measurement Report Request).\n"); } @@ -3714,7 +3655,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt #ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; + PDCP_rlc_AM->statusReportRequired = 0; // FALSE #else PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; @@ -5052,7 +4993,7 @@ check_handovers( && ue_context_p->ue_context.handover_info != NULL && ue_context_p->ue_context.handover_info->forwarding_state == FORWARDING_NO_EMPTY ) { MessageDef *msg_p; - int result; + bool result; protocol_ctxt_t ctxt; do { @@ -5090,7 +5031,7 @@ check_handovers( GTPV1U_ENB_DATA_FORWARDING_IND (msg_p).mode, NULL, NULL ); - if (result != TRUE) { + if (result != true) { LOG_E(RRC, "target enb send data forwarding buffer to PDCP request failed!\n"); } else { LOG_D(RRC, "target enb send data forwarding buffer to PDCP!\n"); @@ -5158,7 +5099,7 @@ check_handovers( GTPV1U_ENB_END_MARKER_IND (msg_p).mode, NULL, NULL ); - if (result != TRUE) { + if (result != true) { LOG_E(RRC, "target enb send spgw buffer to PDCP request failed!\n"); } else { LOG_D(RRC, "target enb send spgw buffer to PDCP!\n"); @@ -5390,7 +5331,7 @@ rrc_eNB_generate_HO_RRCConnectionReconfiguration(const protocol_ctxt_t *const ct #ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; + PDCP_rlc_AM->statusReportRequired = 0; // FALSE #else PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; @@ -6280,10 +6221,7 @@ rrc_eNB_configure_rbs_handover(struct rrc_eNB_ue_context_s *ue_context_p, protoc ctxt_pP, ue_context_p, ue_context_p->ue_context.kenb); - rrc_pdcp_config_security( - ctxt_pP, - ue_context_p, - FALSE); + rrc_pdcp_config_security(ctxt_pP, ue_context_p, false); } // Add a new user (called during the HO procedure) @@ -6361,9 +6299,9 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( UE_sched_ctrl_t *UE_scheduling_control = &(RC.mac[module_id]->UE_info.UE_sched_ctrl[UE_id_mac]); - if (UE_scheduling_control->cdrx_waiting_ack == TRUE) { - UE_scheduling_control->cdrx_waiting_ack = FALSE; - UE_scheduling_control->cdrx_configured = TRUE; // Set to TRUE when RRC Connection Reconfiguration is received + if (UE_scheduling_control->cdrx_waiting_ack == true) { + UE_scheduling_control->cdrx_waiting_ack = false; + UE_scheduling_control->cdrx_configured = true; // Set to TRUE when RRC Connection Reconfiguration is received LOG_I(RRC, "CDRX configuration activated after RRC Connection Reconfiguration Complete reception\n"); } } @@ -6627,7 +6565,7 @@ rrc_eNB_generate_RRCConnectionSetup( ) //----------------------------------------------------------------------------- { - boolean_t is_mtc = ctxt_pP->brOption; + bool is_mtc = ctxt_pP->brOption; LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; LTE_SRB_ToAddModList_t **SRB_configList; LTE_SRB_ToAddMod_t *SRB1_config; @@ -7249,6 +7187,7 @@ rrc_eNB_decode_ccch( LOG_I(RRC," S-TMSI exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p,ue_context_p->ue_context.rnti,ctxt_pP->rnti); if (!NODE_IS_CU(RC.rrc[ctxt_pP->module_id]->node_type)) { + LOG_I(PHY, "remove RNTI %04x\n", ue_context_p->ue_context.rnti); rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti); } else { MessageDef *m = itti_alloc_new_message(TASK_RRC_ENB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); @@ -7284,7 +7223,7 @@ rrc_eNB_decode_ccch( LOG_E(RRC, "%s:%d:%s: rrc_eNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__); if (ue_context_p != NULL) { - ue_context_p->ue_context.Initialue_identity_s_TMSI.presence = TRUE; + ue_context_p->ue_context.Initialue_identity_s_TMSI.presence = true; ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code = mme_code; ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi = m_tmsi; } else { @@ -8766,7 +8705,7 @@ void rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { if ((ctxt_pP->frame&127) == 0 && ctxt_pP->subframe ==0) { if (fd) { - if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == true) { fprintf(fd,"RRC UE rnti %x: S-TMSI %x failure timer %d/8\n", ue_context_p->ue_context.rnti, ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index 575a38ee3d9ddf56102f35fad5a74a3b96b0598f..64b5594dd9e100343c681b747c910d14969747fa 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -84,23 +84,20 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( } //------------------------------------------------------------------------------ -boolean_t -gtpv_data_req( - const protocol_ctxt_t* const ctxt_pP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_sizeP, - uint8_t* const buffer_pP, - const pdcp_transmission_mode_t modeP, - uint32_t task_id -) +bool gtpv_data_req(const protocol_ctxt_t* const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t* const buffer_pP, + const pdcp_transmission_mode_t modeP, + uint32_t task_id) //------------------------------------------------------------------------------ { if(sdu_sizeP == 0) { LOG_I(GTPU,"gtpv_data_req sdu_sizeP == 0"); - return FALSE; + return false; } LOG_D(GTPU,"gtpv_data_req ue rnti %x sdu_sizeP %d rb id %ld", ctxt_pP->rnti, sdu_sizeP, rb_idP); MessageDef *message_p; @@ -129,7 +126,7 @@ gtpv_data_req( GTPV1U_ENB_DATA_FORWARDING_IND (message_p).eNB_index = ctxt_pP->eNB_index; itti_send_msg_to_task (TASK_DATA_FORWARDING, ctxt_pP->instance, message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } else if (task_id == TASK_END_MARKER){ LOG_I(GTPU,"gtpv_data_req task_id = TASK_END_MARKER\n"); @@ -152,23 +149,22 @@ gtpv_data_req( GTPV1U_ENB_END_MARKER_IND (message_p).eNB_index = ctxt_pP->eNB_index; itti_send_msg_to_task (TASK_END_MARKER, ctxt_pP->instance, message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } LOG_E(RRC, "Impossible state\n"); - return FALSE; + return false; } -boolean_t gtpv_data_req_new ( - protocol_ctxt_t *ctxt, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) { +bool gtpv_data_req_new(protocol_ctxt_t *ctxt, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id) { int task; if (sdu_buffer_sizeP==0) diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h index ab789099caeee90bee21c38ce0e9eea9c6160cb9..f991cbd5f62bb46f3c4da73c93de2cc5db80a8ec 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h @@ -60,16 +60,13 @@ void rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ( rrc_eNB_ue_context_t* ue_context_pP ); -boolean_t -gtpv_data_req( - const protocol_ctxt_t* const ctxt_pP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_sizeP, - uint8_t* const buffer_pP, - const pdcp_transmission_mode_t modeP, - uint32_t task_id -); +bool gtpv_data_req(const protocol_ctxt_t* const ctxt_pP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_sizeP, + uint8_t* const buffer_pP, + const pdcp_transmission_mode_t modeP, + uint32_t task_id); #endif /* RRC_ENB_GTPV1U_H_ */ diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index f24c9ab1b616df1c3cf5d781c4feb515c435ffbf..aefbc0183157fb5189a834f830f8e42b8f34d1ac 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -402,15 +402,13 @@ static e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_inte *\param mod_id Instance ID of eNB. *\param ue_index Instance ID of UE in the eNB. *\param security_capabilities The security capabilities received from S1AP. - *\return TRUE if at least one algorithm has been changed else FALSE. + *\return true if at least one algorithm has been changed else false. */ int -rrc_eNB_process_security( - const protocol_ctxt_t *const ctxt_pP, - rrc_eNB_ue_context_t *const ue_context_pP, - security_capabilities_t *security_capabilities_pP -) { - boolean_t changed = FALSE; +rrc_eNB_process_security(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + security_capabilities_t *security_capabilities_pP) { + bool changed = false; LTE_CipheringAlgorithm_r12_t cipheringAlgorithm; e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm integrityProtAlgorithm; /* Save security parameters */ @@ -428,14 +426,14 @@ rrc_eNB_process_security( if (ue_context_pP->ue_context.ciphering_algorithm != cipheringAlgorithm) { ue_context_pP->ue_context.ciphering_algorithm = cipheringAlgorithm; - changed = TRUE; + changed = true; } integrityProtAlgorithm = rrc_eNB_select_integrity (ue_context_pP->ue_context.security_capabilities.integrity_algorithms); if (ue_context_pP->ue_context.integrity_algorithm != integrityProtAlgorithm) { ue_context_pP->ue_context.integrity_algorithm = integrityProtAlgorithm; - changed = TRUE; + changed = true; } LOG_I (RRC, "[eNB %d][UE %x] Selected security algorithms (%p): %lx, %x, %s\n", @@ -532,7 +530,7 @@ rrc_pdcp_config_security( pdcp_p, DCCH, DCCH+2, - (send_security_mode_command == TRUE) ? + (send_security_mode_command == true) ? 0 | (ue_context_pP->ue_context.integrity_algorithm << 4) : (ue_context_pP->ue_context.ciphering_algorithm ) | (ue_context_pP->ue_context.integrity_algorithm << 4), @@ -960,12 +958,12 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char ue_context_p, S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_key); { - uint8_t send_security_mode_command = TRUE; + uint8_t send_security_mode_command = true; #ifndef EXMIMO_IOT if ((ue_context_p->ue_context.ciphering_algorithm == SecurityAlgorithmConfig__cipheringAlgorithm_eea0) && (ue_context_p->ue_context.integrity_algorithm == INTEGRITY_ALGORITHM_NONE)) { - send_security_mode_command = FALSE; + send_security_mode_command = false; } #endif @@ -978,7 +976,7 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char rrc_eNB_generate_SecurityModeCommand ( &ctxt, ue_context_p); - send_security_mode_command = FALSE; + send_security_mode_command = false; // apply ciphering after RRC security command mode rrc_pdcp_config_security( &ctxt, @@ -1414,19 +1412,19 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam /* Save e RAB information for later */ { int j; - boolean_t is_treated[S1AP_MAX_E_RAB] = {FALSE}; + bool is_treated[S1AP_MAX_E_RAB] = {false}; uint8_t nb_of_failed_e_rabs = 0; // keep the previous bearer // the index for the rec for (i = 0; i < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; i++) { - if (is_treated[i] == TRUE) { + if (is_treated[i] == true) { // already treated continue; } for (j = i+1; j < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; j++) { - if (is_treated[j] == FALSE && + if (is_treated[j] == false && S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[j].e_rab_id == S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id) { // handle multiple E-RAB ID ue_context_p->ue_context.modify_e_rab[j].status = E_RAB_STATUS_NEW; @@ -1434,12 +1432,12 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam ue_context_p->ue_context.modify_e_rab[j].cause = S1AP_CAUSE_RADIO_NETWORK; ue_context_p->ue_context.modify_e_rab[j].cause_value = 31;//S1ap_CauseRadioNetwork_multiple_E_RAB_ID_instances; nb_of_failed_e_rabs++; - is_treated[i] = TRUE; - is_treated[j] = TRUE; + is_treated[i] = true; + is_treated[j] = true; } } - if (is_treated[i] == TRUE) { + if (is_treated[i] == true) { // handle multiple E-RAB ID ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW; ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id; @@ -1456,7 +1454,7 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_NAS; ue_context_p->ue_context.modify_e_rab[i].cause_value = 3;//S1ap_CauseNas_unspecified; nb_of_failed_e_rabs++; - is_treated[i] = TRUE; + is_treated[i] = true; continue; } @@ -1474,19 +1472,19 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam ue_context_p->ue_context.modify_e_rab[i].param.nas_pdu.buffer = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].nas_pdu.buffer; ue_context_p->ue_context.modify_e_rab[i].param.sgw_addr = ue_context_p->ue_context.e_rab[j].param.sgw_addr; ue_context_p->ue_context.modify_e_rab[i].param.gtp_teid = ue_context_p->ue_context.e_rab[j].param.gtp_teid; - is_treated[i] = TRUE; + is_treated[i] = true; break; } } - if (is_treated[i] == FALSE) { + if (is_treated[i] == false) { // handle Unknown E-RAB ID ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW; ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id; ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK; ue_context_p->ue_context.modify_e_rab[i].cause_value = 30;//S1ap_CauseRadioNetwork_unknown_E_RAB_ID; nb_of_failed_e_rabs++; - is_treated[i] = TRUE; + is_treated[i] = true; } } @@ -1824,8 +1822,8 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance uint8_t i = 0; for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value)) - || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) { + if ((UE_PF_PO[CC_id][i].enable_flag == true && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value)) + || (UE_PF_PO[CC_id][i].enable_flag != true)) { /* set T = min(Tc,Tue) */ UE_PF_PO[CC_id][i].T = T; /* set UE_ID */ @@ -1845,12 +1843,12 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1))); } - if (UE_PF_PO[CC_id][i].enable_flag == TRUE) { + if (UE_PF_PO[CC_id][i].enable_flag == true) { //paging exist UE log LOG_D(RRC,"[eNB %ld] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); } else { /* set enable_flag */ - UE_PF_PO[CC_id][i].enable_flag = TRUE; + UE_PF_PO[CC_id][i].enable_flag = true; //paging new UE log LOG_D(RRC,"[eNB %ld] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); } diff --git a/openair2/RRC/LTE/rrc_eNB_UE_context.c b/openair2/RRC/LTE/rrc_eNB_UE_context.c index 0d262064b53b162eb57c432e173bca5d88733e09..c9077bfb241f6b739c7eedbfcf1408e184897bbc 100644 --- a/openair2/RRC/LTE/rrc_eNB_UE_context.c +++ b/openair2/RRC/LTE/rrc_eNB_UE_context.c @@ -37,64 +37,6 @@ #include "rrc_eNB_UE_context.h" -//------------------------------------------------------------------------------ -void -uid_linear_allocator_init( - uid_allocator_t *const uid_pP -) -//------------------------------------------------------------------------------ -{ - memset(uid_pP, 0, sizeof(uid_allocator_t)); -} - -//------------------------------------------------------------------------------ -uid_t -uid_linear_allocator_new( - eNB_RRC_INST *const rrc_instance_pP -) -//------------------------------------------------------------------------------ -{ - unsigned int i; - unsigned int bit_index = 1; - uid_t uid = 0; - uid_allocator_t *uia_p = &rrc_instance_pP->uid_allocator; - - for (i=0; i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE; i++) { - if (uia_p->bitmap[i] != UINT_MAX) { - bit_index = 1; - uid = 0; - - while ((uia_p->bitmap[i] & bit_index) == bit_index) { - bit_index = bit_index << 1; - uid += 1; - } - - uia_p->bitmap[i] |= bit_index; - return uid + (i*sizeof(unsigned int)*8); - } - } - - return UINT_MAX; -} - - -//------------------------------------------------------------------------------ -void -uid_linear_allocator_free( - eNB_RRC_INST *rrc_instance_pP, - uid_t uidP -) -//------------------------------------------------------------------------------ -{ - unsigned int i = uidP/sizeof(unsigned int)/8; - unsigned int bit = uidP % (sizeof(unsigned int) * 8); - unsigned int value = ~(0x00000001 << bit); - - if (i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE) { - rrc_instance_pP->uid_allocator.bitmap[i] &= value; - } -} - //------------------------------------------------------------------------------ int rrc_eNB_compare_ue_rnti_id( @@ -134,7 +76,7 @@ rrc_eNB_allocate_new_UE_context( } memset(new_p, 0, sizeof(struct rrc_eNB_ue_context_s)); - new_p->local_uid = uid_linear_allocator_new(rrc_instance_pP); + new_p->local_uid = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator); for(int i = 0; i < NB_RB_MAX; i++) { new_p->ue_context.e_rab[i].xid = -1; @@ -210,7 +152,7 @@ void rrc_eNB_remove_ue_context( RB_REMOVE(rrc_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); rrc_eNB_free_mem_UE_context(ctxt_pP, ue_context_pP); - uid_linear_allocator_free(rrc_instance_pP, ue_context_pP->local_uid); + uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->local_uid); free(ue_context_pP); rrc_instance_pP->Nb_ue --; LOG_I(RRC, diff --git a/openair2/RRC/LTE/rrc_eNB_UE_context.h b/openair2/RRC/LTE/rrc_eNB_UE_context.h index c6420ca9367233a3f04cff900e647b1ec7a2e6b5..89469529dff67320d65d50c53032ee7f047c0ebe 100644 --- a/openair2/RRC/LTE/rrc_eNB_UE_context.h +++ b/openair2/RRC/LTE/rrc_eNB_UE_context.h @@ -34,27 +34,6 @@ #include "COMMON/platform_types.h" #include "rrc_defs.h" - -void -uid_linear_allocator_init( - uid_allocator_t* const uid_pP -); - -uid_t -uid_linear_allocator_new( - eNB_RRC_INST* rrc_instance_pP -); - - -void -uid_linear_allocator_free( - eNB_RRC_INST* rrc_instance_pP, - uid_t uidP -); - - - - int rrc_eNB_compare_ue_rnti_id( struct rrc_eNB_ue_context_s* c1_pP, struct rrc_eNB_ue_context_s* c2_pP diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h index f0456005f5270a5a073aabe8134c87243d758e3e..7bd3fbf758c7f0d3f2d92f0d51c3a743c569a13d 100644 --- a/openair2/RRC/LTE/rrc_proto.h +++ b/openair2/RRC/LTE/rrc_proto.h @@ -457,7 +457,7 @@ mac_rrc_data_ind( const uint8_t *sduP, const sdu_size_t sdu_lenP, const uint8_t mbsfn_sync_areaP, - const boolean_t brOption + const bool brOption ); int8_t @@ -685,7 +685,7 @@ extern RRC_release_list_t rrc_release_info; extern pthread_mutex_t lock_ue_freelist; void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti); -void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag); +void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, bool removeFlag); void release_UE_in_freeList(module_id_t mod_id); /** @}*/ diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 952f32fb101d61e8bc81704341d6abaf6f10632e..67e06914efbbe1118c8e2585350aaecfb826a297 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -49,102 +49,6 @@ extern RAN_CONTEXT_t RC; -int generate_pdcch_ConfigSIB1(NR_PDCCH_ConfigSIB1_t *pdcch_ConfigSIB1, - long ssbSubcarrierSpacing, - long subCarrierSpacingCommon, - channel_bandwidth_t min_channel_bw) { - - nr_ssb_and_cset_mux_pattern_type_t mux_pattern = 0; - - switch (ssbSubcarrierSpacing) { - - case NR_SubcarrierSpacing_kHz15: - if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz15) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_1_NUM_INDEXES; - mux_pattern = table_38213_13_1_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz30) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_2_NUM_INDEXES; - mux_pattern = table_38213_13_2_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else { - AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); - } - break; - - case NR_SubcarrierSpacing_kHz30: - if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz15) { - - if ( (min_channel_bw == bw_5MHz) || (min_channel_bw == bw_10MHz) ) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_3_NUM_INDEXES; - mux_pattern = table_38213_13_3_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else if (min_channel_bw == bw_40MHz) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_5_NUM_INDEXES; - mux_pattern = table_38213_13_5_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else { - AssertFatal(true,"Invalid min_bandwidth\n"); - } - - } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz30) { - - if ( (min_channel_bw == bw_5MHz) || (min_channel_bw == bw_10MHz) ) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_4_NUM_INDEXES; - mux_pattern = table_38213_13_4_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else if (min_channel_bw == bw_40MHz) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_6_NUM_INDEXES; - mux_pattern = table_38213_13_6_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else { - AssertFatal(true,"Invalid min_bandwidth\n"); - } - - } else { - AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); - } - break; - - case NR_SubcarrierSpacing_kHz120: - if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz60) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_7_NUM_INDEXES; - mux_pattern = table_38213_13_7_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz120) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_8_NUM_INDEXES; - mux_pattern = table_38213_13_8_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else { - AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); - } - break; - - case NR_SubcarrierSpacing_kHz240: - if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz60) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_9_NUM_INDEXES; - mux_pattern = table_38213_13_9_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else if (subCarrierSpacingCommon == NR_SubcarrierSpacing_kHz120) { - pdcch_ConfigSIB1->controlResourceSetZero = rand() % TABLE_38213_13_10_NUM_INDEXES; - mux_pattern = table_38213_13_10_c1[pdcch_ConfigSIB1->controlResourceSetZero]; - } else { - AssertFatal(true,"Invalid subCarrierSpacingCommon\n"); - } - break; - - default: - AssertFatal(true,"Invalid ssbSubcarrierSpacing\n"); - break; - } - - - frequency_range_t frequency_range = FR1; - if(ssbSubcarrierSpacing>=60) { - frequency_range = FR2; - } - - pdcch_ConfigSIB1->searchSpaceZero = 0; - if(mux_pattern == NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 && frequency_range == FR1){ - pdcch_ConfigSIB1->searchSpaceZero = rand() % TABLE_38213_13_11_NUM_INDEXES; - } - if(mux_pattern == NR_SSB_AND_CSET_MUX_PATTERN_TYPE1 && frequency_range == FR2){ - pdcch_ConfigSIB1->searchSpaceZero = rand() % TABLE_38213_13_12_NUM_INDEXES; - } - - return 0; -} int nr_rrc_mac_remove_ue(module_id_t mod_idP, @@ -168,7 +72,7 @@ nr_rrc_data_req( { if(sdu_sizeP == 255) { LOG_D(RRC,"sdu_sizeP == 255"); - return FALSE; + return false; } MessageDef *message_p; @@ -204,7 +108,7 @@ nr_rrc_data_req( if (ctxt_pP->enb_flag && NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) pdcp_run(ctxt_pP); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP, @@ -227,14 +131,6 @@ uint16_t mac_rrc_nr_data_req(const module_id_t Mod_idP, rrc_gNB_carrier_data_t *carrier = &RC.nrrrc[Mod_idP]->carrier; NR_BCCH_BCH_Message_t *mib = &carrier->mib; - // Currently we are getting the pdcch_ConfigSIB1 from the configuration file. - // Uncomment this function for a dynamic pdcch_ConfigSIB1. - //channel_bandwidth_t min_channel_bw = bw_10MHz; // Must be obtained based on TS 38.101-1 Table 5.3.5-1 - //generate_pdcch_ConfigSIB1(carrier->pdcch_ConfigSIB1, - // *carrier->servingcellconfigcommon->ssbSubcarrierSpacing, - // carrier->mib.message.choice.mib->subCarrierSpacingCommon, - // min_channel_bw); - mib->message.choice.mib->pdcch_ConfigSIB1.controlResourceSetZero = carrier->pdcch_ConfigSIB1->controlResourceSetZero; mib->message.choice.mib->pdcch_ConfigSIB1.searchSpaceZero = carrier->pdcch_ConfigSIB1->searchSpaceZero; @@ -306,74 +202,6 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, return 0; } -int8_t nr_mac_rrc_data_ind(const module_id_t module_idP, - const int CC_id, - const frame_t frameP, - const sub_frame_t sub_frameP, - const int UE_id, - const rnti_t rntiP, - const rb_id_t srb_idP, - const uint8_t *sduP, - const sdu_size_t sdu_lenP, - const boolean_t brOption) { - - if (NODE_IS_DU(RC.nrrrc[module_idP]->node_type)) { - LOG_W(RRC,"[DU %d][RAPROC] Received SDU for CCCH on SRB %ld length %d for UE id %d RNTI %x \n", - module_idP, srb_idP, sdu_lenP, UE_id, rntiP); - - // Generate DUtoCURRCContainer - // call do_RRCSetup like full procedure and extract masterCellGroup - NR_CellGroupConfig_t cellGroupConfig; - NR_ServingCellConfigCommon_t *scc=RC.nrrrc[module_idP]->carrier.servingcellconfigcommon; - NR_ServingCellConfig_t *servingcellconfigdedicated = RC.nrrrc[module_idP]->configuration.scd; - memset(&cellGroupConfig,0,sizeof(cellGroupConfig)); - - struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[module_idP]); - ue_context_p->ue_id_rnti = rntiP; - ue_context_p->ue_context.rnti = rntiP; - ue_context_p->ue_context.random_ue_identity = rntiP; - ue_context_p->ue_context.Srb0.Active = 1; - RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[module_idP]->rrc_ue_head, ue_context_p); - - fill_initial_cellGroupConfig(ue_context_p->local_uid,&cellGroupConfig,scc,servingcellconfigdedicated,&RC.nrrrc[module_idP]->configuration); - - MessageDef* tmp=itti_alloc_new_message_sized(TASK_RRC_GNB, 0, F1AP_INITIAL_UL_RRC_MESSAGE, sizeof(f1ap_initial_ul_rrc_message_t) + sdu_lenP); - f1ap_initial_ul_rrc_message_t *msg = &F1AP_INITIAL_UL_RRC_MESSAGE(tmp); - - asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, - NULL, - (void *)&cellGroupConfig, - msg->du2cu_rrc_container, - F1AP_MAX_DU2CU_RRC_LENGTH); - - if (enc_rval.encoded == -1) { - LOG_E(F1AP,"Could not encoded cellGroupConfig, failed element %s\n",enc_rval.failed_type->name); - exit(-1); - } - /* do ITTI message */ - msg->du2cu_rrc_container_length = (enc_rval.encoded+7)/8; - msg->crnti=rntiP; - msg->rrc_container=(uint8_t*) (msg+1); // Made extra room after the struct with itti_alloc_msg_sized() - memcpy(msg->rrc_container, sduP, sdu_lenP); - msg->rrc_container_length=sdu_lenP; - itti_send_msg_to_task(TASK_DU_F1, 0, tmp); - return(0); - } - - protocol_ctxt_t ctxt; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, GNB_FLAG_YES, rntiP, frameP, sub_frameP,0); - - if((srb_idP & RAB_OFFSET) == CCCH) { - LOG_D(NR_RRC, "[gNB %d] Received SDU for CCCH on SRB %ld\n", module_idP, srb_idP); - ctxt.brOption = brOption; - if (sdu_lenP > 0) { - nr_rrc_gNB_decode_ccch(&ctxt, sduP, sdu_lenP, NULL, CC_id); - } - } - - return 0; -} - void nr_mac_gNB_rrc_ul_failure(const module_id_t Mod_instP, const int CC_idP, const frame_t frameP, diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index 49de6cdb03ba79fc7baf3e8bf8f6fe956d564c36..6aaa96a8e74b3cd45793066a5806bab7076d75f1 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -42,6 +42,7 @@ #include <nr/nr_common.h> #include <softmodem-common.h> +#include "executables/softmodem-common.h" #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "asn1_msg.h" #include "../nr_rrc_proto.h" @@ -198,8 +199,7 @@ int xer_nr_sprint (char *string, size_t string_size, asn_TYPE_descriptor_t *td, uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { asn_enc_rval_t enc_rval; - rrc_gNB_carrier_data_t *carrier = &rrc->carrier; - const gNB_RrcConfigurationReq *configuration = &rrc->configuration; + rrc_gNB_carrier_data_t *carrier = &rrc->carrier; NR_BCCH_BCH_Message_t *mib = &carrier->mib; NR_ServingCellConfigCommon_t *scc = carrier->servingcellconfigcommon; @@ -226,11 +226,14 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { AssertFatal(scc->ssbSubcarrierSpacing != NULL, "scc->ssbSubcarrierSpacing is null\n"); int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; frequency_range_t frequency_range = band<100?FR1:FR2; - int ssb_subcarrier_offset; - if(frequency_range == FR1) - ssb_subcarrier_offset = (configuration->ssb_SubcarrierOffset<24) ? (configuration->ssb_SubcarrierOffset<<*scc->ssbSubcarrierSpacing) : configuration->ssb_SubcarrierOffset; - else - ssb_subcarrier_offset = configuration->ssb_SubcarrierOffset; + int ssb_subcarrier_offset = 31; // default value for NSA + if (get_softmodem_params()->sa) { + uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); + int scs_scaling = scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000 ? 3 : 1; + ssb_subcarrier_offset = (absolute_diff/scs_scaling)%24; + if(frequency_range == FR2) + ssb_subcarrier_offset >>= 1; // this assumes 120kHz SCS for SSB and subCarrierSpacingCommon (only option supported by OAI for now) + } mib->message.choice.mib->ssb_SubcarrierOffset = ssb_subcarrier_offset&15; /* @@ -303,11 +306,10 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc,uint32_t frame) { return((enc_rval.encoded+7)/8); } -uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, - gNB_RrcConfigurationReq *configuration - ) { - asn_enc_rval_t enc_rval; +uint16_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, + gNB_RrcConfigurationReq *configuration) { + asn_enc_rval_t enc_rval; NR_BCCH_DL_SCH_Message_t *sib1_message = CALLOC(1,sizeof(NR_BCCH_DL_SCH_Message_t)); carrier->siblock1 = sib1_message; sib1_message->message.present = NR_BCCH_DL_SCH_MessageType_PR_c1; @@ -343,7 +345,6 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, if(configuration->mnc_digit_length[i] == 3) { asn1cSequenceAdd(nr_plmn->mnc.list, NR_MCC_MNC_Digit_t, mnc0); *mnc0=(configuration->mnc[i]/100)%10; - mnc/=10; } asn1cSequenceAdd(nr_plmn->mnc.list, NR_MCC_MNC_Digit_t, mnc1); *mnc1=(mnc/10)%10; @@ -658,12 +659,9 @@ uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, (void *)sib1_message, carrier->SIB1, NR_MAX_SIB_LENGTH/8); - AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - - if (enc_rval.encoded==-1) { - return(-1); - } + AssertFatal(enc_rval.encoded <= NR_MAX_SIB_LENGTH, "ASN1 encoded length %zd bits. 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.\n", enc_rval.encoded); return((enc_rval.encoded+7)/8); } @@ -986,35 +984,10 @@ uint8_t do_RRCReject(uint8_t Mod_id, return((enc_rval.encoded+7)/8); } -// TODO: Implement to b_SRS = 1 and b_SRS = 2 -long rrc_get_max_nr_csrs(uint8_t max_rbs, long b_SRS) { - - if(b_SRS>0) { - LOG_E(NR_RRC,"rrc_get_max_nr_csrs(): Not implemented yet for b_SRS>0\n"); - return 0; // This c_srs is always valid - } - - const uint16_t m_SRS[64] = { 4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 48, 52, 56, 60, 64, 72, 72, 76, 80, 88, - 96, 96, 104, 112, 120, 120, 120, 128, 128, 128, 132, 136, 144, 144, 144, 144, 152, 160, - 160, 160, 168, 176, 184, 192, 192, 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256, - 256, 264, 272, 272, 272 }; - - long c_srs = 0; - uint16_t m = 4; - for(int c = 1; c<64; c++) { - if(m_SRS[c]>m && m_SRS[c]<max_rbs) { - c_srs = c; - m = m_SRS[c]; - } - } - - return c_srs; -} - void fill_default_downlinkBWP(NR_BWP_Downlink_t *bwp, int bwp_loop, - NR_ServingCellConfig_t *servingcellconfigdedicated, - NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *scc, const gNB_RrcConfigurationReq *configuration) { /// BWP common configuration @@ -1160,8 +1133,8 @@ void fill_default_downlinkBWP(NR_BWP_Downlink_t *bwp, void fill_default_uplinkBWP(NR_BWP_Uplink_t *ubwp, int bwp_loop, - NR_ServingCellConfig_t *servingcellconfigdedicated, - NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *scc, const gNB_RrcConfigurationReq *configuration, int uid) { @@ -1180,6 +1153,8 @@ void fill_default_uplinkBWP(NR_BWP_Uplink_t *ubwp, ubwp->bwp_Common->genericParameters.cyclicPrefix = scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.cyclicPrefix; } + int curr_bwp = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); + ubwp->bwp_Common->rach_ConfigCommon = NULL; ubwp->bwp_Common->pusch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon; ubwp->bwp_Common->pucch_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon; @@ -1192,125 +1167,17 @@ void fill_default_uplinkBWP(NR_BWP_Uplink_t *ubwp, ubwp->bwp_Dedicated->pucch_Config->present = NR_SetupRelease_PUCCH_Config_PR_setup; NR_PUCCH_Config_t *pucch_Config = calloc(1,sizeof(*pucch_Config)); ubwp->bwp_Dedicated->pucch_Config->choice.setup=pucch_Config; + pucch_Config->resourceSetToAddModList = calloc(1,sizeof(*pucch_Config->resourceSetToAddModList)); pucch_Config->resourceSetToReleaseList = NULL; - NR_PUCCH_ResourceSet_t *pucchresset0=calloc(1,sizeof(*pucchresset0)); - NR_PUCCH_ResourceSet_t *pucchresset1=calloc(1,sizeof(*pucchresset1)); - pucchresset0->pucch_ResourceSetId = 0; - NR_PUCCH_ResourceId_t *pucchresset0id0=calloc(1,sizeof(*pucchresset0id0)); - *pucchresset0id0=0; - ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id0); - pucchresset0->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset0); - pucchresset1->pucch_ResourceSetId = 1; - NR_PUCCH_ResourceId_t *pucchresset1id0=calloc(1,sizeof(*pucchresset1id0)); - *pucchresset1id0=1; - ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id0); - pucchresset1->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset1); pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; - int curr_bwp = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE); - NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0)); - pucchres0->pucch_ResourceId=0; - pucchres0->startingPRB=(8+uid) % (curr_bwp/2); - LOG_D(NR_RRC, "pucchres0->startPRB %ld uid %d curr_bwp %d\n", pucchres0->startingPRB, uid, curr_bwp); - pucchres0->intraSlotFrequencyHopping=NULL; - pucchres0->secondHopPRB=NULL; - pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; - pucchres0->format.choice.format0=calloc(1,sizeof(*pucchres0->format.choice.format0)); - pucchres0->format.choice.format0->initialCyclicShift=0; - pucchres0->format.choice.format0->nrofSymbols=1; - pucchres0->format.choice.format0->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0); - NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); - pucchres2->pucch_ResourceId=1; - pucchres2->startingPRB=0; - pucchres2->intraSlotFrequencyHopping=NULL; - pucchres2->secondHopPRB=NULL; - pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; - pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2)); - pucchres2->format.choice.format2->nrofPRBs=8; - pucchres2->format.choice.format2->nrofSymbols=1; - pucchres2->format.choice.format2->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2); - pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2)); - pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup; - NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2)); - pucch_Config->format2->choice.setup = pucchfmt2; - pucchfmt2->interslotFrequencyHopping=NULL; - pucchfmt2->additionalDMRS=NULL; - pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate)); - *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot35; - pucchfmt2->nrofSlots=NULL; - pucchfmt2->pi2BPSK=NULL; - pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI)); - *pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true; - - // PUCCH config - Scheduling request configuration - pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList)); - NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig)); - schedulingRequestResourceConfig->schedulingRequestResourceId = 1; - schedulingRequestResourceConfig->schedulingRequestID = 0; - schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset)); - schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40; // 40 slot period - // note: make sure that there is no issue here. Later choose the RNTI accordingly. - // Here we would be limited to 3 UEs on this resource (1 1/2 Frames 30 kHz SCS, 5 ms TDD periodicity => slots 7,8,9). - // This should be a temporary resource until the first RRCReconfiguration gives new pucch resources. - // Check for above configuration and exit for now if it is not the case - AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30, - "SCS != 30kHz\n"); - AssertFatal(scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity==NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms5, - "TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity); - schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8; - schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); - *schedulingRequestResourceConfig->resource = 0; - ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig); - pucch_Config->schedulingRequestResourceToReleaseList=NULL; - - pucch_Config->multi_CSI_PUCCH_ResourceList=NULL; - pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK)); - long *delay[8]; - for (int i=0;i<8;i++) { - delay[i] = calloc(1,sizeof(*delay[i])); - AssertFatal(configuration->minRXTXTIME >=2 && configuration->minRXTXTIME <7, "check minRXTXTIME %d\n",configuration->minRXTXTIME); - *delay[i] = i+configuration->minRXTXTIME; - ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); - } - pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList)); - NR_PUCCH_SpatialRelationInfo_t *pucchspatial = calloc(1,sizeof(*pucchspatial)); - pucchspatial->pucch_SpatialRelationInfoId = 1; - pucchspatial->servingCellId = NULL; - if(configuration->do_CSIRS) { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; - pucchspatial->referenceSignal.choice.csi_RS_Index = 0; - } - else { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_ssb_Index; - pucchspatial->referenceSignal.choice.ssb_Index = 0; - } - pucchspatial->pucch_PathlossReferenceRS_Id = 0; - pucchspatial->p0_PUCCH_Id = 1; - pucchspatial->closedLoopIndex = NR_PUCCH_SpatialRelationInfo__closedLoopIndex_i0; - ASN_SEQUENCE_ADD(&pucch_Config->spatialRelationInfoToAddModList->list,pucchspatial); - pucch_Config->spatialRelationInfoToReleaseList=NULL; - pucch_Config->pucch_PowerControl=calloc(1,sizeof(*pucch_Config->pucch_PowerControl)); - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4 = 0; - pucch_Config->pucch_PowerControl->p0_Set = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->p0_Set)); - NR_P0_PUCCH_t *p00 = calloc(1,sizeof(*p00)); - p00->p0_PUCCH_Id=1; - p00->p0_PUCCH_Value = 0; - ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->p0_Set->list,p00); - pucch_Config->pucch_PowerControl->pathlossReferenceRSs = NULL; + config_pucch_resset0(pucch_Config, uid, curr_bwp, NULL); + config_pucch_resset1(pucch_Config, NULL); + set_pucch_power_config(pucch_Config, configuration->do_CSIRS); + + scheduling_request_config(scc, pucch_Config); + set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME); // PUSCH config ubwp->bwp_Dedicated->pusch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pusch_Config)); @@ -1464,8 +1331,8 @@ void fill_default_uplinkBWP(NR_BWP_Uplink_t *ubwp, void fill_initial_SpCellConfig(int uid, NR_SpCellConfig_t *SpCellConfig, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, const gNB_RrcConfigurationReq *configuration) { // This assert will never happen in the current implementation because NUMBER_OF_UE_MAX = 4. @@ -1490,81 +1357,11 @@ void fill_initial_SpCellConfig(int uid, initialUplinkBWP->pucch_Config->choice.setup=pucch_Config; pucch_Config->resourceSetToAddModList = calloc(1,sizeof(*pucch_Config->resourceSetToAddModList)); pucch_Config->resourceSetToReleaseList = NULL; - NR_PUCCH_ResourceSet_t *pucchresset0=calloc(1,sizeof(*pucchresset0)); - NR_PUCCH_ResourceSet_t *pucchresset1=calloc(1,sizeof(*pucchresset1)); - pucchresset0->pucch_ResourceSetId = 0; - NR_PUCCH_ResourceId_t *pucchresset0id0=calloc(1,sizeof(*pucchresset0id0)); - *pucchresset0id0=0; - ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id0); - pucchresset0->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset0); - - pucchresset1->pucch_ResourceSetId = 1; - NR_PUCCH_ResourceId_t *pucchresset1id0=calloc(1,sizeof(*pucchresset1id0)); - *pucchresset1id0=1; - ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id0); - pucchresset1->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset1); - pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; - // configure one single PUCCH0 opportunity for initial connection procedure - // one symbol (13) - NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0)); - pucchres0->pucch_ResourceId=0; - //pucchres0->startingPRB=0; - pucchres0->startingPRB=(8+uid) % (curr_bwp/2); - LOG_D(NR_RRC, "pucchres0->startPRB %ld uid %d curr_bwp %d\n", pucchres0->startingPRB, uid, curr_bwp); - pucchres0->intraSlotFrequencyHopping=NULL; - pucchres0->secondHopPRB=NULL; - pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; - pucchres0->format.choice.format0=calloc(1,sizeof(*pucchres0->format.choice.format0)); - pucchres0->format.choice.format0->initialCyclicShift=0; - pucchres0->format.choice.format0->nrofSymbols=1; - pucchres0->format.choice.format0->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0); - - NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); - pucchres2->pucch_ResourceId=1; - pucchres2->startingPRB=0; - pucchres2->intraSlotFrequencyHopping=NULL; - pucchres2->secondHopPRB=NULL; - pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; - pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2)); - pucchres2->format.choice.format2->nrofPRBs=8; - pucchres2->format.choice.format2->nrofSymbols=1; - pucchres2->format.choice.format2->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2); - - pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2)); - pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup; - NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2)); - pucch_Config->format2->choice.setup = pucchfmt2; - pucchfmt2->interslotFrequencyHopping=NULL; - pucchfmt2->additionalDMRS=NULL; - pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate)); - *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot35; - pucchfmt2->nrofSlots=NULL; - pucchfmt2->pi2BPSK=NULL; - pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI)); - *pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true; - - pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList)); - NR_PUCCH_SpatialRelationInfo_t *pucchspatial = calloc(1,sizeof(*pucchspatial)); - pucchspatial->pucch_SpatialRelationInfoId = 1; - pucchspatial->servingCellId = NULL; - if(configuration->do_CSIRS) { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; - pucchspatial->referenceSignal.choice.csi_RS_Index = 0; - } - else { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_ssb_Index; - pucchspatial->referenceSignal.choice.ssb_Index = 0; - } - pucchspatial->pucch_PathlossReferenceRS_Id = 0; - pucchspatial->p0_PUCCH_Id = 1; - pucchspatial->closedLoopIndex = NR_PUCCH_SpatialRelationInfo__closedLoopIndex_i0; - ASN_SEQUENCE_ADD(&pucch_Config->spatialRelationInfoToAddModList->list,pucchspatial); + config_pucch_resset0(pucch_Config, uid, curr_bwp, NULL); + config_pucch_resset1(pucch_Config, NULL); + set_pucch_power_config(pucch_Config, configuration->do_CSIRS); initialUplinkBWP->pusch_Config = calloc(1,sizeof(*initialUplinkBWP->pusch_Config)); initialUplinkBWP->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup; @@ -1638,106 +1435,13 @@ void fill_initial_SpCellConfig(int uid, pusch_Config->uci_OnPUSCH=NULL; pusch_Config->tp_pi2BPSK=NULL; + // We are using do_srs = 0 here because the periodic SRS will only be enabled in update_cellGroupConfig() if do_srs == 1 initialUplinkBWP->srs_Config = calloc(1,sizeof(*initialUplinkBWP->srs_Config)); - initialUplinkBWP->srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup; - NR_SRS_Config_t *srs_Config = calloc(1,sizeof(*srs_Config)); - initialUplinkBWP->srs_Config->choice.setup=srs_Config; - srs_Config->srs_ResourceSetToReleaseList=NULL; - srs_Config->srs_ResourceSetToAddModList=calloc(1,sizeof(*srs_Config->srs_ResourceSetToAddModList)); - NR_SRS_ResourceSet_t *srs_resset0=calloc(1,sizeof(*srs_resset0)); - srs_resset0->srs_ResourceSetId = 0; - srs_resset0->srs_ResourceIdList=calloc(1,sizeof(*srs_resset0->srs_ResourceIdList)); - NR_SRS_ResourceId_t *srs_resset0_id=calloc(1,sizeof(*srs_resset0_id)); - *srs_resset0_id=0; - ASN_SEQUENCE_ADD(&srs_resset0->srs_ResourceIdList->list,srs_resset0_id); - srs_Config->srs_ResourceToReleaseList=NULL; - - if (configuration->do_SRS) { - srs_resset0->resourceType.present = NR_SRS_ResourceSet__resourceType_PR_periodic; - srs_resset0->resourceType.choice.periodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.periodic)); - srs_resset0->resourceType.choice.periodic->associatedCSI_RS = NULL; - } else { - srs_resset0->resourceType.present = NR_SRS_ResourceSet__resourceType_PR_aperiodic; - srs_resset0->resourceType.choice.aperiodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.aperiodic)); - srs_resset0->resourceType.choice.aperiodic->aperiodicSRS_ResourceTrigger=1; - srs_resset0->resourceType.choice.aperiodic->csi_RS=NULL; - srs_resset0->resourceType.choice.aperiodic->slotOffset= calloc(1,sizeof(*srs_resset0->resourceType.choice.aperiodic->slotOffset)); - *srs_resset0->resourceType.choice.aperiodic->slotOffset=2; - srs_resset0->resourceType.choice.aperiodic->ext1=NULL; - } - - srs_resset0->usage=NR_SRS_ResourceSet__usage_codebook; - srs_resset0->alpha = calloc(1,sizeof(*srs_resset0->alpha)); - *srs_resset0->alpha = NR_Alpha_alpha1; - srs_resset0->p0=calloc(1,sizeof(*srs_resset0->p0)); - *srs_resset0->p0=-80; - srs_resset0->pathlossReferenceRS=NULL; - srs_resset0->srs_PowerControlAdjustmentStates=NULL; - ASN_SEQUENCE_ADD(&srs_Config->srs_ResourceSetToAddModList->list,srs_resset0); - srs_Config->srs_ResourceToReleaseList=NULL; - srs_Config->srs_ResourceToAddModList=calloc(1,sizeof(*srs_Config->srs_ResourceToAddModList)); - NR_SRS_Resource_t *srs_res0=calloc(1,sizeof(*srs_res0)); - srs_res0->srs_ResourceId=0; - srs_res0->nrofSRS_Ports=NR_SRS_Resource__nrofSRS_Ports_port1; - srs_res0->ptrs_PortIndex=NULL; - srs_res0->transmissionComb.present=NR_SRS_Resource__transmissionComb_PR_n2; - srs_res0->transmissionComb.choice.n2=calloc(1,sizeof(*srs_res0->transmissionComb.choice.n2)); - srs_res0->transmissionComb.choice.n2->combOffset_n2=0; - srs_res0->transmissionComb.choice.n2->cyclicShift_n2=0; - srs_res0->resourceMapping.startPosition = 2 + uid%2; - srs_res0->resourceMapping.nrofSymbols=NR_SRS_Resource__resourceMapping__nrofSymbols_n1; - srs_res0->resourceMapping.repetitionFactor=NR_SRS_Resource__resourceMapping__repetitionFactor_n1; - srs_res0->freqDomainPosition=0; - srs_res0->freqDomainShift=0; - srs_res0->freqHopping.b_SRS=0; - srs_res0->freqHopping.b_hop=0; - srs_res0->freqHopping.c_SRS = rrc_get_max_nr_csrs( - NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, 275), - srs_res0->freqHopping.b_SRS); - srs_res0->groupOrSequenceHopping=NR_SRS_Resource__groupOrSequenceHopping_neither; + config_srs(initialUplinkBWP->srs_Config, scc, uid, 0); - if (configuration->do_SRS) { - srs_res0->resourceType.present= NR_SRS_Resource__resourceType_PR_periodic; - srs_res0->resourceType.choice.periodic=calloc(1,sizeof(*srs_res0->resourceType.choice.periodic)); - srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl160; - srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.choice.sl160 = 17 + (uid>1)*10; // 17/17/.../147/157 are mixed slots - } else { - srs_res0->resourceType.present= NR_SRS_Resource__resourceType_PR_aperiodic; - srs_res0->resourceType.choice.aperiodic=calloc(1,sizeof(*srs_res0->resourceType.choice.aperiodic)); - } + scheduling_request_config(scc, pucch_Config); - srs_res0->sequenceId=40; - srs_res0->spatialRelationInfo=calloc(1,sizeof(*srs_res0->spatialRelationInfo)); - srs_res0->spatialRelationInfo->servingCellId=NULL; - srs_res0->spatialRelationInfo->referenceSignal.present=NR_SRS_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; - srs_res0->spatialRelationInfo->referenceSignal.choice.csi_RS_Index=0; - ASN_SEQUENCE_ADD(&srs_Config->srs_ResourceToAddModList->list,srs_res0); - - // configure Scheduling request - // 40 slot period - pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList)); - NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig)); - schedulingRequestResourceConfig->schedulingRequestResourceId = 1; - schedulingRequestResourceConfig->schedulingRequestID = 0; - schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset)); - schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40; - AssertFatal(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing==NR_SubcarrierSpacing_kHz30, - "SCS != 30kHz\n"); - - schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8; - schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); - *schedulingRequestResourceConfig->resource = 0; - ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig); - - pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK)); - long *delay[8]; - for (int i=0;i<8;i++) { - delay[i] = calloc(1,sizeof(*delay[i])); - AssertFatal(configuration->minRXTXTIME >= 2 && configuration->minRXTXTIME < 7, - "minRXTXTIME is %d but should be within [2,7)\n", configuration->minRXTXTIME); - *delay[i] = i + configuration->minRXTXTIME; - ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); - } + set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME); SpCellConfig->spCellConfigDedicated->initialDownlinkBWP = calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->initialDownlinkBWP)); NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP; @@ -1799,13 +1503,13 @@ void fill_initial_SpCellConfig(int uid, bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->maxLength=NULL; bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition)); - *bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1; - bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation = NR_PDSCH_Config__resourceAllocation_resourceAllocationType1; - bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling; - bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling = calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling)); - bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = - calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize)); - *bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = NR_PDSCH_Config__prb_BundlingType__staticBundling__bundleSize_wideband; + *bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_AdditionalPosition = NR_DMRS_DownlinkConfig__dmrs_AdditionalPosition_pos1; + bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation = NR_PDSCH_Config__resourceAllocation_resourceAllocationType1; + bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling; + bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling = calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling)); + bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = + calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize)); + *bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = NR_PDSCH_Config__prb_BundlingType__staticBundling__bundleSize_wideband; bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList=calloc(1,sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToAddModList)); NR_TCI_State_t *tcic; @@ -1886,14 +1590,13 @@ void fill_initial_SpCellConfig(int uid, csires0->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ResourceConfigToAddModList->list,csires0); - NR_CSI_ResourceConfig_t *csires1 = calloc(1,sizeof(*csires1)); csires1->csi_ResourceConfigId=1; csires1->csi_RS_ResourceSetList.present = NR_CSI_ResourceConfig__csi_RS_ResourceSetList_PR_nzp_CSI_RS_SSB; csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB = calloc(1,sizeof(*csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB)); csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList = calloc(1,sizeof(*csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList)); NR_CSI_SSB_ResourceSetId_t *ssbres00 = calloc(1,sizeof(*ssbres00)); - *ssbres00 = 0; + *ssbres00 = 0; ASN_SEQUENCE_ADD(&csires1->csi_RS_ResourceSetList.choice.nzp_CSI_RS_SSB->csi_SSB_ResourceSetList->list,ssbres00); csires1->bwp_Id = 0; csires1->resourceType = NR_CSI_ResourceConfig__resourceType_periodic; @@ -1913,8 +1616,8 @@ void fill_initial_SpCellConfig(int uid, } NR_PUCCH_CSI_Resource_t *pucchcsires1 = calloc(1,sizeof(*pucchcsires1)); - pucchcsires1->uplinkBandwidthPartId=0; - pucchcsires1->pucch_Resource=1; + pucchcsires1->uplinkBandwidthPartId = 0; + pucchcsires1->pucch_Resource = *pucch_Config->resourceSetToAddModList->list.array[1]->resourceList.list.array[0]; csi_MeasConfig->csi_ReportConfigToAddModList = calloc(1,sizeof(*csi_MeasConfig->csi_ReportConfigToAddModList)); csi_MeasConfig->csi_ReportConfigToReleaseList = NULL; if (pdsch_AntennaPorts > 1) { @@ -2010,6 +1713,7 @@ void fill_initial_SpCellConfig(int uid, csirep2->ext1 = NULL; ASN_SEQUENCE_ADD(&csi_MeasConfig->csi_ReportConfigToAddModList->list,csirep2); } + pdsch_servingcellconfig->codeBlockGroupTransmission = NULL; pdsch_servingcellconfig->xOverhead = NULL; pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH = calloc(1, sizeof(*pdsch_servingcellconfig->nrofHARQ_ProcessesForPDSCH)); @@ -2139,7 +1843,7 @@ NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, long drbId, NR return rlc_BearerConfig; } -void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup, int use_rlc_um_for_drb, uint8_t configure_srb, uint8_t bearer_id_start, uint8_t nb_bearers_to_setup, long *priority ) { +void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup, int use_rlc_um_for_drb, uint8_t configure_srb, uint8_t bearer_id_start, uint8_t nb_bearers_to_setup, long *priority) { cellGroupConfig->cellGroupId = 0; cellGroupConfig->rlc_BearerToReleaseList = NULL; @@ -2163,16 +1867,35 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGr } void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, + const int uid, NR_UE_NR_Capability_t *uecap, const gNB_RrcConfigurationReq* configuration) { NR_SpCellConfig_t *SpCellConfig = cellGroupConfig->spCellConfig; + if (SpCellConfig == NULL) return; NR_ServingCellConfigCommon_t *scc = configuration ? configuration->scc : NULL; - // Set DL MCS table if(scc) { + + // SRS configuration + if (configuration->do_SRS && + SpCellConfig && + SpCellConfig->spCellConfigDedicated && + SpCellConfig->spCellConfigDedicated->uplinkConfig && + SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP) { + if (!SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config) { + SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config = + calloc(1,sizeof(*SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config)); + } + config_srs(SpCellConfig->spCellConfigDedicated->uplinkConfig->initialUplinkBWP->srs_Config, + scc, + uid, + configuration->do_SRS); + } + + // Set DL MCS table NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP; set_dl_mcs_table(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing, configuration->force_256qam_off ? NULL : uecap, SpCellConfig, bwp_Dedicated, scc); @@ -2184,14 +1907,14 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, set_dl_mcs_table(scs, configuration->force_256qam_off ? NULL : uecap, SpCellConfig, bwp->bwp_Dedicated, scc); } } - } + } } void fill_initial_cellGroupConfig(int uid, NR_CellGroupConfig_t *cellGroupConfig, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, const gNB_RrcConfigurationReq *configuration) { NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = NULL; @@ -2208,36 +1931,33 @@ void fill_initial_cellGroupConfig(int uid, cellGroupConfig->rlc_BearerToReleaseList = NULL; /* mac CellGroup Config */ - if (1) { - mac_CellGroupConfig = calloc(1, sizeof(*mac_CellGroupConfig)); - if (1) { - mac_CellGroupConfig->schedulingRequestConfig = calloc(1, sizeof(*mac_CellGroupConfig->schedulingRequestConfig)); - mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = CALLOC(1,sizeof(*mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList)); - struct NR_SchedulingRequestToAddMod *schedulingrequestlist; - schedulingrequestlist = CALLOC(1,sizeof(*schedulingrequestlist)); - schedulingrequestlist->schedulingRequestId = 0; - schedulingrequestlist->sr_ProhibitTimer = CALLOC(1,sizeof(*schedulingrequestlist->sr_ProhibitTimer)); - *(schedulingrequestlist->sr_ProhibitTimer) = 0; - schedulingrequestlist->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n64; - ASN_SEQUENCE_ADD(&(mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list),schedulingrequestlist); - } - mac_CellGroupConfig->bsr_Config = calloc(1, sizeof(*mac_CellGroupConfig->bsr_Config)); - mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; - mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf80; - mac_CellGroupConfig->tag_Config = calloc(1, sizeof(*mac_CellGroupConfig->tag_Config)); - mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; - mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*mac_CellGroupConfig->tag_Config->tag_ToAddModList)); - struct NR_TAG *tag=calloc(1,sizeof(*tag)); - tag->tag_Id = 0; - tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity; - ASN_SEQUENCE_ADD(&mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag); - mac_CellGroupConfig->phr_Config = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config)); - mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup; - mac_CellGroupConfig->phr_Config->choice.setup = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config->choice.setup)); - mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf10; - mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf10; - mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB1; - } + mac_CellGroupConfig = calloc(1, sizeof(*mac_CellGroupConfig)); + + mac_CellGroupConfig->bsr_Config = calloc(1, sizeof(*mac_CellGroupConfig->bsr_Config)); + mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; + mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf80; + mac_CellGroupConfig->tag_Config = calloc(1, sizeof(*mac_CellGroupConfig->tag_Config)); + mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; + mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*mac_CellGroupConfig->tag_Config->tag_ToAddModList)); + struct NR_TAG *tag=calloc(1,sizeof(*tag)); + tag->tag_Id = 0; + tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity; + ASN_SEQUENCE_ADD(&mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag); + mac_CellGroupConfig->phr_Config = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config)); + mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup; + mac_CellGroupConfig->phr_Config->choice.setup = calloc(1, sizeof(*mac_CellGroupConfig->phr_Config->choice.setup)); + mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf10; + mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf10; + mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB1; + + mac_CellGroupConfig->schedulingRequestConfig = calloc(1, sizeof(*mac_CellGroupConfig->schedulingRequestConfig)); + mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = CALLOC(1,sizeof(*mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList)); + struct NR_SchedulingRequestToAddMod *schedulingrequestlist = CALLOC(1,sizeof(*schedulingrequestlist)); + schedulingrequestlist->schedulingRequestId = 0; + schedulingrequestlist->sr_ProhibitTimer = NULL; + schedulingrequestlist->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n64; + ASN_SEQUENCE_ADD(&(mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list),schedulingrequestlist); + cellGroupConfig->mac_CellGroupConfig = mac_CellGroupConfig; physicalCellGroupConfig = calloc(1,sizeof(*physicalCellGroupConfig)); @@ -2247,7 +1967,7 @@ void fill_initial_cellGroupConfig(int uid, cellGroupConfig->physicalCellGroupConfig = physicalCellGroupConfig; cellGroupConfig->spCellConfig = calloc(1,sizeof(*cellGroupConfig->spCellConfig)); - + fill_initial_SpCellConfig(uid,cellGroupConfig->spCellConfig,scc,servingcellconfigdedicated,configuration); cellGroupConfig->sCellToAddModList = NULL; @@ -2255,13 +1975,14 @@ void fill_initial_cellGroupConfig(int uid, } //------------------------------------------------------------------------------ -int16_t do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, - uint8_t *const buffer, - const uint8_t transaction_id, - OCTET_STRING_t *masterCellGroup_from_DU, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, - const gNB_RrcConfigurationReq *configuration) +int do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, + uint8_t *const buffer, + const uint8_t transaction_id, + const uint8_t *masterCellGroup, + int masterCellGroup_len, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, + const gNB_RrcConfigurationReq *configuration) //------------------------------------------------------------------------------ { asn_enc_rval_t enc_rval; @@ -2271,7 +1992,6 @@ int16_t do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, NR_SRB_ToAddMod_t *SRB1_config = NULL; NR_PDCP_Config_t *pdcp_Config = NULL; NR_CellGroupConfig_t *cellGroupConfig = NULL; - char masterCellGroup_buf[3000]; AssertFatal(ue_context_pP != NULL,"ue_context_p is null\n"); gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; @@ -2314,38 +2034,14 @@ int16_t do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, ie->radioBearerConfig.securityConfig = NULL; /****************************** masterCellGroup ******************************/ - /* TODO */ - if (masterCellGroup_from_DU) { - memcpy(&ie->masterCellGroup,masterCellGroup_from_DU,sizeof(*masterCellGroup_from_DU)); - // decode masterCellGroup OCTET_STRING received from DU and place in ue context - uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, //might be added prefix later - (void **)&cellGroupConfig, - (uint8_t *)masterCellGroup_from_DU->buf, - masterCellGroup_from_DU->size, 0, 0); - } - else { - cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - fill_initial_cellGroupConfig(ue_context_pP->local_uid,cellGroupConfig,scc,servingcellconfigdedicated,configuration); - - enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, - NULL, - (void *)cellGroupConfig, - masterCellGroup_buf, - 3000); - - if(enc_rval.encoded == -1) { - LOG_E(NR_RRC, "ASN1 message CellGroupConfig encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; - } - - if (OCTET_STRING_fromBuf(&ie->masterCellGroup, masterCellGroup_buf, (enc_rval.encoded+7)/8) == -1) { - LOG_E(NR_RRC, "fatal: OCTET_STRING_fromBuf failed\n"); - return -1; - } - } - + DevAssert(masterCellGroup && masterCellGroup_len > 0); + ie->masterCellGroup.buf = malloc(masterCellGroup_len); + AssertFatal(ie->masterCellGroup.buf != NULL, "could not allocate memory for masterCellGroup\n"); + memcpy(ie->masterCellGroup.buf, masterCellGroup, masterCellGroup_len); + ie->masterCellGroup.size = masterCellGroup_len; + + // decode masterCellGroup OCTET_STRING received from DU and place in ue context + uper_decode(NULL, &asn_DEF_NR_CellGroupConfig, (void **)&cellGroupConfig, masterCellGroup, masterCellGroup_len, 0, 0); ue_p->masterCellGroup = cellGroupConfig; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { @@ -2629,6 +2325,7 @@ int16_t do_RRCReconfiguration( if(cellGroupConfig!=NULL){ update_cellGroupConfig(cellGroupConfig, + ue_context_pP->local_uid, ue_context_pP ? ue_context_pP->ue_context.UE_Capability_nr : NULL, configuration); diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h index e79f79493d74dfa35f060d0f650102e1369d987f..1d6be68f5c98849250eaa55275b933c2732b7856 100644 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.h +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h @@ -73,9 +73,7 @@ uint8_t do_MIB_NR(gNB_RRC_INST *rrc, @param carrier pointer to Carrier information @param configuration Pointer Configuration Request structure @return size of encoded bit stream in bytes*/ -uint8_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, - gNB_RrcConfigurationReq *configuration - ); +uint16_t do_SIB1_NR(rrc_gNB_carrier_data_t *carrier, gNB_RrcConfigurationReq *configuration); uint8_t do_SIB23_NR(rrc_gNB_carrier_data_t *carrier, gNB_RrcConfigurationReq *configuration); @@ -103,17 +101,18 @@ uint8_t do_RRCReject(uint8_t Mod_id, void fill_initial_SpCellConfig(int uid, NR_SpCellConfig_t *SpCellConfig, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, const gNB_RrcConfigurationReq *configuration); void fill_initial_cellGroupConfig(int uid, NR_CellGroupConfig_t *cellGroupConfig, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, const gNB_RrcConfigurationReq *configuration); void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, + const int uid, NR_UE_NR_Capability_t *uecap, const gNB_RrcConfigurationReq *configuration); @@ -125,13 +124,14 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, uint8_t nb_bearers_to_setup, long *priority); -int16_t do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, - uint8_t *const buffer, - const uint8_t transaction_id, - OCTET_STRING_t *masterCellGroup_from_DU, - NR_ServingCellConfigCommon_t *scc, - NR_ServingCellConfig_t *servingcellconfigdedicated, - const gNB_RrcConfigurationReq *configuration); +int do_RRCSetup(rrc_gNB_ue_context_t *const ue_context_pP, + uint8_t *const buffer, + const uint8_t transaction_id, + const uint8_t *masterCellGroup, + int masterCellGroup_len, + const NR_ServingCellConfigCommon_t *scc, + const NR_ServingCellConfig_t *servingcellconfigdedicated, + const gNB_RrcConfigurationReq *configuration); uint8_t do_NR_SecurityModeCommand( const protocol_ctxt_t *const ctxt_pP, diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h new file mode 100644 index 0000000000000000000000000000000000000000..1943490cd6accb206de4cda7a66ab2c9f2409079 --- /dev/null +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -0,0 +1,34 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * conmnc_digit_lengtht@openairinterface.org + */ + +#ifndef MAC_RRC_DL_H +#define MAC_RRC_DL_H + +#include "platform_types.h" +#include "f1ap_messages_types.h" + +typedef void (*dl_rrc_message_transfer_func_t)(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc); + +struct nr_mac_rrc_dl_if_s; +void mac_rrc_dl_direct_init(struct nr_mac_rrc_dl_if_s *mac_rrc); +void mac_rrc_dl_f1ap_init(struct nr_mac_rrc_dl_if_s *mac_rrc); + +#endif /* MAC_RRC_DL_H */ diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c new file mode 100644 index 0000000000000000000000000000000000000000..5c8d9d9d5bd1b759a8a0e3997986afc695539b8c --- /dev/null +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -0,0 +1,37 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include "nr_rrc_defs.h" + +#include "mac_rrc_dl.h" +#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" + +static void dl_rrc_message_transfer_direct(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) +{ + /* TODO how to manage inter-thread communication? */ + + dl_rrc_message(module_id, dl_rrc); +} + +void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc) +{ + mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_direct; +} diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c new file mode 100644 index 0000000000000000000000000000000000000000..40f3b4b6eaa70bc170ce3c112c854b7bb5ba3327 --- /dev/null +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -0,0 +1,44 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 + * + * 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. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * conmnc_digit_lengtht@openairinterface.org + */ + +#include "mac_rrc_dl.h" +#include "nr_rrc_defs.h" + +static void dl_rrc_message_transfer_f1ap(module_id_t module_id, const f1ap_dl_rrc_message_t *dl_rrc) +{ + /* TODO call F1AP function directly? no real-time constraint here */ + + MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE); + f1ap_dl_rrc_message_t *msg = &F1AP_DL_RRC_MESSAGE(message_p); + *msg = *dl_rrc; + if (dl_rrc->rrc_container) { + msg->rrc_container = malloc(dl_rrc->rrc_container_length); + AssertFatal(msg->rrc_container != NULL, "out of memory\n"); + msg->rrc_container_length = dl_rrc->rrc_container_length; + memcpy(msg->rrc_container, dl_rrc->rrc_container, dl_rrc->rrc_container_length); + } + itti_send_msg_to_task (TASK_CU_F1, module_id, message_p); +} + +void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc) +{ + mac_rrc->dl_rrc_message_transfer = dl_rrc_message_transfer_f1ap; +} diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c index 3517cf76a00194dded308101cd1f9cbbb5ccfb54..5d1e3e97d0717fdf8f0de491ee837be60904c635 100644 --- a/openair2/RRC/NR/nr_rrc_config.c +++ b/openair2/RRC/NR/nr_rrc_config.c @@ -71,7 +71,7 @@ void rrc_coreset_config(NR_ControlResourceSet_t *coreset, coreset->pdcch_DMRS_ScramblingID = NULL; } -uint64_t get_ssb_bitmap(NR_ServingCellConfigCommon_t *scc) { +uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc) { uint64_t bitmap=0; switch (scc->ssb_PositionsInBurst->present) { case 1 : @@ -138,8 +138,7 @@ void set_csirs_periodicity(NR_NZP_CSI_RS_Resource_t *nzpcsi0, int uid, int nb_sl } } - -void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon, +void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_CSI_MeasConfig_t *csi_MeasConfig, int uid, int num_dl_antenna_ports, @@ -324,6 +323,130 @@ void config_csiim(int do_csirs, int dl_antenna_ports, int curr_bwp, csi_MeasConfig->csi_IM_ResourceSetToReleaseList = NULL; } +// TODO: Implement to b_SRS = 1 and b_SRS = 2 +long rrc_get_max_nr_csrs(const uint8_t max_rbs, const long b_SRS) { + + if(b_SRS>0) { + LOG_E(NR_RRC,"rrc_get_max_nr_csrs(): Not implemented yet for b_SRS>0\n"); + return 0; // This c_srs is always valid + } + + const uint16_t m_SRS[64] = { 4, 8, 12, 16, 16, 20, 24, 24, 28, 32, 36, 40, 48, 48, 52, 56, 60, 64, 72, 72, 76, 80, 88, + 96, 96, 104, 112, 120, 120, 120, 128, 128, 128, 132, 136, 144, 144, 144, 144, 152, 160, + 160, 160, 168, 176, 184, 192, 192, 192, 192, 208, 216, 224, 240, 240, 240, 240, 256, 256, + 256, 264, 272, 272, 272 }; + + long c_srs = 0; + uint16_t m = 4; + for(int c = 1; c<64; c++) { + if(m_SRS[c]>m && m_SRS[c]<max_rbs) { + c_srs = c; + m = m_SRS[c]; + } + } + + return c_srs; +} + +void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, + const NR_ServingCellConfigCommon_t *servingcellconfigcommon, + const int uid, + const int do_srs) { + + setup_release_srs_Config->present = NR_SetupRelease_SRS_Config_PR_setup; + + NR_SRS_Config_t *srs_Config; + if (setup_release_srs_Config->choice.setup) { + srs_Config = setup_release_srs_Config->choice.setup; + if (srs_Config->srs_ResourceSetToReleaseList) { + free(srs_Config->srs_ResourceSetToReleaseList); + } + if (srs_Config->srs_ResourceSetToAddModList) { + free(srs_Config->srs_ResourceSetToAddModList); + } + if (srs_Config->srs_ResourceToReleaseList) { + free(srs_Config->srs_ResourceToReleaseList); + } + if (srs_Config->srs_ResourceToAddModList) { + free(srs_Config->srs_ResourceToAddModList); + } + free(srs_Config); + } + + setup_release_srs_Config->choice.setup = calloc(1,sizeof(*setup_release_srs_Config->choice.setup)); + srs_Config = setup_release_srs_Config->choice.setup; + + srs_Config->srs_ResourceSetToReleaseList = NULL; + + srs_Config->srs_ResourceSetToAddModList = calloc(1,sizeof(*srs_Config->srs_ResourceSetToAddModList)); + NR_SRS_ResourceSet_t *srs_resset0 = calloc(1,sizeof(*srs_resset0)); + srs_resset0->srs_ResourceSetId = 0; + srs_resset0->srs_ResourceIdList = calloc(1,sizeof(*srs_resset0->srs_ResourceIdList)); + NR_SRS_ResourceId_t *srs_resset0_id = calloc(1,sizeof(*srs_resset0_id)); + *srs_resset0_id = 0; + ASN_SEQUENCE_ADD(&srs_resset0->srs_ResourceIdList->list, srs_resset0_id); + srs_Config->srs_ResourceToReleaseList=NULL; + if (do_srs) { + srs_resset0->resourceType.present = NR_SRS_ResourceSet__resourceType_PR_periodic; + srs_resset0->resourceType.choice.periodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.periodic)); + srs_resset0->resourceType.choice.periodic->associatedCSI_RS = NULL; + } else { + srs_resset0->resourceType.present = NR_SRS_ResourceSet__resourceType_PR_aperiodic; + srs_resset0->resourceType.choice.aperiodic = calloc(1,sizeof(*srs_resset0->resourceType.choice.aperiodic)); + srs_resset0->resourceType.choice.aperiodic->aperiodicSRS_ResourceTrigger=1; + srs_resset0->resourceType.choice.aperiodic->csi_RS=NULL; + srs_resset0->resourceType.choice.aperiodic->slotOffset = calloc(1,sizeof(*srs_resset0->resourceType.choice.aperiodic->slotOffset)); + *srs_resset0->resourceType.choice.aperiodic->slotOffset = 2; + srs_resset0->resourceType.choice.aperiodic->ext1 = NULL; + } + srs_resset0->usage=NR_SRS_ResourceSet__usage_codebook; + srs_resset0->alpha = calloc(1,sizeof(*srs_resset0->alpha)); + *srs_resset0->alpha = NR_Alpha_alpha1; + srs_resset0->p0 = calloc(1,sizeof(*srs_resset0->p0)); + *srs_resset0->p0 =-80; + srs_resset0->pathlossReferenceRS = NULL; + srs_resset0->srs_PowerControlAdjustmentStates = NULL; + ASN_SEQUENCE_ADD(&srs_Config->srs_ResourceSetToAddModList->list,srs_resset0); + + srs_Config->srs_ResourceToReleaseList = NULL; + + srs_Config->srs_ResourceToAddModList = calloc(1,sizeof(*srs_Config->srs_ResourceToAddModList)); + NR_SRS_Resource_t *srs_res0=calloc(1,sizeof(*srs_res0)); + srs_res0->srs_ResourceId = 0; + srs_res0->nrofSRS_Ports = NR_SRS_Resource__nrofSRS_Ports_port1; + srs_res0->ptrs_PortIndex = NULL; + srs_res0->transmissionComb.present = NR_SRS_Resource__transmissionComb_PR_n2; + srs_res0->transmissionComb.choice.n2 = calloc(1,sizeof(*srs_res0->transmissionComb.choice.n2)); + srs_res0->transmissionComb.choice.n2->combOffset_n2 = 0; + srs_res0->transmissionComb.choice.n2->cyclicShift_n2 = 0; + srs_res0->resourceMapping.startPosition = 2 + uid%2; + srs_res0->resourceMapping.nrofSymbols = NR_SRS_Resource__resourceMapping__nrofSymbols_n1; + srs_res0->resourceMapping.repetitionFactor = NR_SRS_Resource__resourceMapping__repetitionFactor_n1; + srs_res0->freqDomainPosition = 0; + srs_res0->freqDomainShift = 0; + srs_res0->freqHopping.b_SRS = 0; + srs_res0->freqHopping.b_hop = 0; + srs_res0->freqHopping.c_SRS = servingcellconfigcommon ? + rrc_get_max_nr_csrs( + NRRIV2BW(servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth, 275), + srs_res0->freqHopping.b_SRS) : 0; + srs_res0->groupOrSequenceHopping = NR_SRS_Resource__groupOrSequenceHopping_neither; + if (do_srs) { + srs_res0->resourceType.present = NR_SRS_Resource__resourceType_PR_periodic; + srs_res0->resourceType.choice.periodic = calloc(1,sizeof(*srs_res0->resourceType.choice.periodic)); + srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.present = NR_SRS_PeriodicityAndOffset_PR_sl160; + srs_res0->resourceType.choice.periodic->periodicityAndOffset_p.choice.sl160 = 17 + (uid>1)*10; // 17/17/.../147/157 are mixed slots + } else { + srs_res0->resourceType.present = NR_SRS_Resource__resourceType_PR_aperiodic; + srs_res0->resourceType.choice.aperiodic = calloc(1,sizeof(*srs_res0->resourceType.choice.aperiodic)); + } + srs_res0->sequenceId = 40; + srs_res0->spatialRelationInfo = calloc(1,sizeof(*srs_res0->spatialRelationInfo)); + srs_res0->spatialRelationInfo->servingCellId = NULL; + srs_res0->spatialRelationInfo->referenceSignal.present = NR_SRS_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; + srs_res0->spatialRelationInfo->referenceSignal.choice.csi_RS_Index = 0; + ASN_SEQUENCE_ADD(&srs_Config->srs_ResourceToAddModList->list,srs_res0); +} void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, NR_ServingCellConfigCommon_t *scc, @@ -331,6 +454,7 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, int rbsize, int mcs_table) { + NR_Phy_Parameters_t *phy_Parameters = &cap->phy_Parameters; int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0]; NR_BandNR_t *nr_bandnr = CALLOC(1,sizeof(NR_BandNR_t)); nr_bandnr->bandNR = band; @@ -344,8 +468,8 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, *bandNRinfo->pdsch_256QAM_FR2 = NR_BandNR__pdsch_256QAM_FR2_supported; } else{ - cap->phy_Parameters.phy_ParametersFR1 = CALLOC(1,sizeof(*cap->phy_Parameters.phy_ParametersFR1)); - NR_Phy_ParametersFR1_t *phy_fr1 = cap->phy_Parameters.phy_ParametersFR1; + phy_Parameters->phy_ParametersFR1 = CALLOC(1,sizeof(*phy_Parameters->phy_ParametersFR1)); + NR_Phy_ParametersFR1_t *phy_fr1 = phy_Parameters->phy_ParametersFR1; phy_fr1->pdsch_256QAM_FR1 = CALLOC(1,sizeof(*phy_fr1->pdsch_256QAM_FR1)); *phy_fr1->pdsch_256QAM_FR1 = NR_Phy_ParametersFR1__pdsch_256QAM_FR1_supported; } @@ -366,9 +490,12 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, *fs_cc->supportedModulationOrderDL = NR_ModulationOrder_qam256; ASN_SEQUENCE_ADD(&fs->featureSetsDownlinkPerCC->list, fs_cc); } + + phy_Parameters->phy_ParametersFRX_Diff = CALLOC(1,sizeof(*phy_Parameters->phy_ParametersFRX_Diff)); + phy_Parameters->phy_ParametersFRX_Diff->pucch_F0_2WithoutFH = NULL; } -void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc, +void nr_rrc_config_dl_tda(const NR_ServingCellConfigCommon_t *scc, NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList, int curr_bwp) { @@ -421,7 +548,7 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){ pusch_timedomainresourceallocation->k2 = CALLOC(1,sizeof(long)); *pusch_timedomainresourceallocation->k2 = k2; pusch_timedomainresourceallocation->mappingType = NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB; - pusch_timedomainresourceallocation->startSymbolAndLength = get_SLIV(0,13); + pusch_timedomainresourceallocation->startSymbolAndLength = get_SLIV(0,13); ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation); if(frame_type==TDD) { @@ -454,10 +581,210 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){ } } -void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap, +void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time) { + + pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK)); + long *delay[8]; + for (int i=0;i<8;i++) { + delay[i] = calloc(1,sizeof(*delay[i])); + *delay[i] = i+min_feedback_time; + ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); + } +} + +// PUCCH resource set 0 for configuration with O_uci <= 2 bits and/or a positive or negative SR (section 9.2.1 of 38.213) +void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int curr_bwp, NR_UE_NR_Capability_t *uecap) { + + NR_PUCCH_ResourceSet_t *pucchresset = calloc(1,sizeof(*pucchresset)); + pucchresset->pucch_ResourceSetId = 0; + NR_PUCCH_ResourceId_t *pucchid=calloc(1,sizeof(*pucchid)); + *pucchid=0; + ASN_SEQUENCE_ADD(&pucchresset->resourceList.list,pucchid); + pucchresset->maxPayloadSize=NULL; + + if(uecap) { + long *pucch_F0_2WithoutFH = uecap->phy_Parameters.phy_ParametersFRX_Diff->pucch_F0_2WithoutFH; + AssertFatal(pucch_F0_2WithoutFH == NULL,"UE does not support PUCCH F0 without frequency hopping. Current configuration is without FH\n"); + } + + NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0)); + pucchres0->pucch_ResourceId=*pucchid; + pucchres0->startingPRB= (8 + uid) % curr_bwp; + pucchres0->intraSlotFrequencyHopping=NULL; + pucchres0->secondHopPRB=NULL; + pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; + pucchres0->format.choice.format0=calloc(1,sizeof(*pucchres0->format.choice.format0)); + pucchres0->format.choice.format0->initialCyclicShift=0; + pucchres0->format.choice.format0->nrofSymbols=1; + pucchres0->format.choice.format0->startingSymbolIndex=13; + ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0); + + ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset); +} + + +// PUCCH resource set 1 for configuration with O_uci > 2 bits (currently format2) +void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, NR_UE_NR_Capability_t *uecap) { + + NR_PUCCH_ResourceSet_t *pucchresset=calloc(1,sizeof(*pucchresset)); + pucchresset->pucch_ResourceSetId = 1; + NR_PUCCH_ResourceId_t *pucchressetid=calloc(1,sizeof(*pucchressetid)); + *pucchressetid=2; + ASN_SEQUENCE_ADD(&pucchresset->resourceList.list,pucchressetid); + pucchresset->maxPayloadSize=NULL; + + if(uecap) { + long *pucch_F0_2WithoutFH = uecap->phy_Parameters.phy_ParametersFRX_Diff->pucch_F0_2WithoutFH; + AssertFatal(pucch_F0_2WithoutFH == NULL,"UE does not support PUCCH F2 without frequency hopping. Current configuration is without FH\n"); + } + + NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); + pucchres2->pucch_ResourceId=*pucchressetid; + pucchres2->startingPRB=0; + pucchres2->intraSlotFrequencyHopping=NULL; + pucchres2->secondHopPRB=NULL; + pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; + pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2)); + pucchres2->format.choice.format2->nrofPRBs=8; + pucchres2->format.choice.format2->nrofSymbols=1; + pucchres2->format.choice.format2->startingSymbolIndex=13; + ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2); + + ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset); + + pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2)); + pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup; + NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2)); + pucch_Config->format2->choice.setup = pucchfmt2; + pucchfmt2->interslotFrequencyHopping=NULL; + pucchfmt2->additionalDMRS=NULL; + pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate)); + *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot35; + pucchfmt2->nrofSlots=NULL; + pucchfmt2->pi2BPSK=NULL; + + // to check UE capabilities for that in principle + pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI)); + *pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true; + +} + +void set_pucch_power_config(NR_PUCCH_Config_t *pucch_Config, int do_csirs) { + + pucch_Config->pucch_PowerControl = calloc(1,sizeof(*pucch_Config->pucch_PowerControl)); + NR_P0_PUCCH_t *p00 = calloc(1,sizeof(*p00)); + p00->p0_PUCCH_Id = 1; + p00->p0_PUCCH_Value = 0; + pucch_Config->pucch_PowerControl->p0_Set = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->p0_Set)); + ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->p0_Set->list,p00); + + pucch_Config->pucch_PowerControl->pathlossReferenceRSs = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->pathlossReferenceRSs)); + struct NR_PUCCH_PathlossReferenceRS *PL_ref_RS = calloc(1,sizeof(*PL_ref_RS)); + PL_ref_RS->pucch_PathlossReferenceRS_Id = 0; + if(do_csirs) { + PL_ref_RS->referenceSignal.present = NR_PUCCH_PathlossReferenceRS__referenceSignal_PR_csi_RS_Index; + PL_ref_RS->referenceSignal.choice.csi_RS_Index = 0; + } + else { + PL_ref_RS->referenceSignal.present = NR_PUCCH_PathlossReferenceRS__referenceSignal_PR_ssb_Index; + PL_ref_RS->referenceSignal.choice.ssb_Index = 0; + } + ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->pathlossReferenceRSs->list,PL_ref_RS); + + pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0)); + *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = 0; + pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2)); + *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = 0; + + pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList)); + pucch_Config->spatialRelationInfoToReleaseList=NULL; + NR_PUCCH_SpatialRelationInfo_t *pucchspatial = calloc(1,sizeof(*pucchspatial)); + pucchspatial->pucch_SpatialRelationInfoId = 1; + pucchspatial->servingCellId = NULL; + if(do_csirs) { + pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; + pucchspatial->referenceSignal.choice.csi_RS_Index = 0; + } + else { + pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_ssb_Index; + pucchspatial->referenceSignal.choice.ssb_Index = 0; + } + + pucchspatial->pucch_PathlossReferenceRS_Id = PL_ref_RS->pucch_PathlossReferenceRS_Id; + pucchspatial->p0_PUCCH_Id = p00->p0_PUCCH_Id; + pucchspatial->closedLoopIndex = NR_PUCCH_SpatialRelationInfo__closedLoopIndex_i0; + ASN_SEQUENCE_ADD(&pucch_Config->spatialRelationInfoToAddModList->list,pucchspatial); +} + +static void set_SR_periodandoffset(NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig, + const NR_ServingCellConfigCommon_t *scc) +{ + const NR_TDD_UL_DL_Pattern_t *tdd = scc->tdd_UL_DL_ConfigurationCommon ? &scc->tdd_UL_DL_ConfigurationCommon->pattern1 : NULL; + int sr_slot = 1; // in FDD SR in slot 1 + if(tdd) + sr_slot = tdd->nrofDownlinkSlots; // SR in the first uplink slot + + schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset)); + + if(sr_slot<10){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl10 = sr_slot; + return; + } + if(sr_slot<20){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl20; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl20 = sr_slot; + return; + } + if(sr_slot<40){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl40; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = sr_slot; + return; + } + if(sr_slot<80){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl80; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl80 = sr_slot; + return; + } + if(sr_slot<160){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl160; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl160 = sr_slot; + return; + } + if(sr_slot<320){ + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl320; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl320 = sr_slot; + return; + } + schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl640; + schedulingRequestResourceConfig->periodicityAndOffset->choice.sl640 = sr_slot; +} + +void scheduling_request_config(const NR_ServingCellConfigCommon_t *scc, + NR_PUCCH_Config_t *pucch_Config) { + + // format with <=2 bits in pucch resource set 0 + NR_PUCCH_ResourceSet_t *pucchresset = pucch_Config->resourceSetToAddModList->list.array[0]; + // assigning the 1st pucch resource in the set to scheduling request + NR_PUCCH_ResourceId_t *pucchressetid = pucchresset->resourceList.list.array[0]; + + pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList)); + NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig)); + schedulingRequestResourceConfig->schedulingRequestResourceId = 1; + schedulingRequestResourceConfig->schedulingRequestID = 0; + + set_SR_periodandoffset(schedulingRequestResourceConfig, scc); + + schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); + *schedulingRequestResourceConfig->resource = *pucchressetid; + ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig); +} + +void set_dl_mcs_table(int scs, + NR_UE_NR_Capability_t *cap, NR_SpCellConfig_t *SpCellConfig, NR_BWP_DownlinkDedicated_t *bwp_Dedicated, - NR_ServingCellConfigCommon_t *scc) { + const NR_ServingCellConfigCommon_t *scc) { if (cap == NULL){ bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NULL; @@ -494,7 +821,7 @@ void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap, if(bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL) bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = calloc(1, sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table)); *bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NR_PDSCH_Config__mcs_Table_qam256; -// set table 2 in correct entry in SpCellConfig->spCellConfigDedicated->csi_MeasConfig->csi_ReportConfigToAddModList->list + // set table 2 in correct entry in SpCellConfig->spCellConfigDedicated->csi_MeasConfig->csi_ReportConfigToAddModList->list AssertFatal(SpCellConfig!=NULL,"SpCellConfig shouldn't be null\n"); AssertFatal(SpCellConfig->spCellConfigDedicated!=NULL,"SpCellConfigDedicated shouldn't be null\n"); if (SpCellConfig->spCellConfigDedicated->csi_MeasConfig && diff --git a/openair2/RRC/NR/nr_rrc_config.h b/openair2/RRC/NR/nr_rrc_config.h index 8b28e2d584fbdb5552d7ab020a9dda8f56616827..27aebcf94b09cef2799d8f8571ebd3cdac5a2e2b 100644 --- a/openair2/RRC/NR/nr_rrc_config.h +++ b/openair2/RRC/NR/nr_rrc_config.h @@ -111,16 +111,22 @@ typedef struct physicalcellgroup_s{ long RNTI_Value[MAX_NUM_CCs]; }physicalcellgroup_t; -uint64_t get_ssb_bitmap(NR_ServingCellConfigCommon_t *scc); +uint64_t get_ssb_bitmap(const NR_ServingCellConfigCommon_t *scc); void rrc_coreset_config(NR_ControlResourceSet_t *coreset, int bwp_id, int curr_bwp, uint64_t ssb_bitmap); -void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc, +void nr_rrc_config_dl_tda(const NR_ServingCellConfigCommon_t *scc, NR_PDSCH_TimeDomainResourceAllocationList_t *pdsch_TimeDomainAllocationList, int curr_bwp); void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay); -void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon, +void config_pucch_resset0(NR_PUCCH_Config_t *pucch_Config, int uid, int curr_bwp, NR_UE_NR_Capability_t *uecap); +void config_pucch_resset1(NR_PUCCH_Config_t *pucch_Config, NR_UE_NR_Capability_t *uecap); +void set_dl_DataToUL_ACK(NR_PUCCH_Config_t *pucch_Config, int min_feedback_time); +void set_pucch_power_config(NR_PUCCH_Config_t *pucch_Config, int do_csirs); +void scheduling_request_config(const NR_ServingCellConfigCommon_t *scc, + NR_PUCCH_Config_t *pucch_Config); +void config_csirs(const NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_CSI_MeasConfig_t *csi_MeasConfig, int uid, int num_dl_antenna_ports, @@ -128,15 +134,19 @@ void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon, int do_csirs); void config_csiim(int do_csirs, int dl_antenna_ports, int curr_bwp, NR_CSI_MeasConfig_t *csi_MeasConfig); -void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap, +void config_srs(NR_SetupRelease_SRS_Config_t *setup_release_srs_Config, + const NR_ServingCellConfigCommon_t *servingcellconfigcommon, + const int uid, + const int do_srs); +void set_dl_mcs_table(int scs, + NR_UE_NR_Capability_t *cap, NR_SpCellConfig_t *SpCellConfig, NR_BWP_DownlinkDedicated_t *bwp_Dedicated, - NR_ServingCellConfigCommon_t *scc); + const NR_ServingCellConfigCommon_t *scc); void prepare_sim_uecap(NR_UE_NR_Capability_t *cap, NR_ServingCellConfigCommon_t *scc, int numerology, int rbsize, int mcs_table); - #endif diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 89ae9c1d2b2a2cac0b940815c91b73cbdfc29874..e9d9766f41b5a7621acc97b1a8a6ffef372d05ce 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -36,12 +36,13 @@ #include <string.h> #include "collection/tree.h" +#include "collection/linear_alloc.h" #include "nr_rrc_types.h" +#include "common/ngran_types.h" #include "COMMON/platform_constants.h" #include "COMMON/platform_types.h" -#include "RRC/LTE/rrc_defs.h" -//#include "LAYER2/RLC/rlc.h" +#include "mac_rrc_dl.h" //#include "COMMON/mac_rrc_primitives.h" @@ -79,17 +80,6 @@ #include "commonDef.h" - -/*I will change the name of the structure for compile purposes--> hope not to undo this process*/ - -typedef unsigned int uid_nr_t; -#define NR_UID_LINEAR_ALLOCATOR_BITMAP_SIZE (((MAX_MOBILES_PER_GNB/8)/sizeof(unsigned int)) + 1) - -typedef struct nr_uid_linear_allocator_s { - unsigned int bitmap[NR_UID_LINEAR_ALLOCATOR_BITMAP_SIZE]; -} nr_uid_allocator_t; - - #define PROTOCOL_NR_RRC_CTXT_UE_FMT PROTOCOL_CTXT_FMT #define PROTOCOL_NR_RRC_CTXT_UE_ARGS(CTXT_Pp) PROTOCOL_NR_CTXT_ARGS(CTXT_Pp) @@ -173,7 +163,7 @@ typedef struct UE_RRC_INFO_NR_s { } __attribute__ ((__packed__)) NR_UE_RRC_INFO; typedef struct UE_S_TMSI_NR_s { - boolean_t presence; + bool presence; uint16_t amf_set_id; uint8_t amf_pointer; uint32_t fiveg_tmsi; @@ -282,12 +272,11 @@ typedef struct pdu_session_param_s { typedef struct gNB_RRC_UE_s { uint8_t primaryCC_id; - LTE_SCellToAddMod_r10_t sCell_config[2]; NR_SRB_ToAddModList_t *SRB_configList; - NR_SRB_ToAddModList_t *SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + NR_SRB_ToAddModList_t *SRB_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; NR_DRB_ToAddModList_t *DRB_configList; - NR_DRB_ToAddModList_t *DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; - NR_DRB_ToReleaseList_t *DRB_Release_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + NR_DRB_ToAddModList_t *DRB_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; + NR_DRB_ToReleaseList_t *DRB_Release_configList2[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER]; uint8_t DRB_active[8]; NR_SRB_INFO SI; @@ -295,7 +284,7 @@ typedef struct gNB_RRC_UE_s { NR_SRB_INFO_TABLE_ENTRY Srb1; NR_SRB_INFO_TABLE_ENTRY Srb2; NR_MeasConfig_t *measConfig; - HANDOVER_INFO *handover_info; + NR_HANDOVER_INFO *handover_info; NR_MeasResults_t *measResults; @@ -352,7 +341,7 @@ typedef struct gNB_RRC_UE_s { /* Number of e_rab to be modified in the list */ uint8_t nb_of_modify_e_rabs; uint8_t nb_of_failed_e_rabs; - e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; + nr_e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; /* Total number of pdu session already setup in the list */ uint8_t setup_pdu_sessions; /* Number of pdu session to be setup in the list */ @@ -363,7 +352,7 @@ typedef struct gNB_RRC_UE_s { pdu_session_param_t modify_pdusession[NR_NB_RB_MAX]; /* list of e_rab to be setup by RRC layers */ /* list of pdu session to be setup by RRC layers */ - e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; + nr_e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; pdu_session_param_t pduSession[NR_NB_RB_MAX];//[NGAP_MAX_PDU_SESSION]; //release e_rabs uint8_t nb_release_of_e_rabs; @@ -410,8 +399,6 @@ typedef struct gNB_RRC_UE_s { } gNB_RRC_UE_t; -typedef uid_t ue_uid_t; - typedef struct rrc_gNB_ue_context_s { /* Tree related data */ RB_ENTRY(rrc_gNB_ue_context_s) entries; @@ -422,7 +409,7 @@ typedef struct rrc_gNB_ue_context_s { rnti_t ue_id_rnti; // another key for protocol layers but should not be used as a key for RB tree - ue_uid_t local_uid; + uid_t local_uid; /* UE id for initial connection to S1AP */ struct gNB_RRC_UE_s ue_context; @@ -435,7 +422,7 @@ typedef struct { uint8_t sizeof_MIB; uint8_t *SIB1; - uint8_t sizeof_SIB1; + uint16_t sizeof_SIB1; uint8_t *SIB23; uint8_t sizeof_SIB23; @@ -447,7 +434,8 @@ typedef struct { NR_BCCH_BCH_Message_t mib; NR_BCCH_BCH_Message_t *mib_DU; - NR_BCCH_DL_SCH_Message_t *siblock1_DU; + NR_SIB1_t *siblock1_DU; + //NR_BCCH_DL_SCH_Message_t *siblock1_DU; NR_SIB1_t *sib1; NR_SIB2_t *sib2; NR_SIB3_t *sib3; @@ -479,6 +467,11 @@ typedef struct { int do_drb_integrity; } nr_security_configuration_t; +typedef struct nr_mac_rrc_dl_if_s { + /* TODO add other message types as necessary */ + dl_rrc_message_transfer_func_t dl_rrc_message_transfer; +} nr_mac_rrc_dl_if_t; + //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -488,7 +481,7 @@ typedef struct gNB_RRC_INST_s { int module_id; eth_params_t eth_params_s; rrc_gNB_carrier_data_t carrier; - nr_uid_allocator_t uid_allocator; // for rrc_ue_head + uid_allocator_t uid_allocator; RB_HEAD(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s) rrc_ue_head; // ue_context tree key search by rnti int Nb_ue; hash_table_t *initial_id2_s1ap_ids; // key is content is rrc_ue_s1ap_ids_t @@ -528,6 +521,8 @@ typedef struct gNB_RRC_INST_s { // security configuration (preferred algorithms) nr_security_configuration_t security; + + nr_mac_rrc_dl_if_t mac_rrc; } gNB_RRC_INST; #include "nr_rrc_proto.h" //should be put here otherwise compilation error diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 6a320123de201dc17401ae2d3b6ac5e5e4c3ffed..b90cf4dfa4cc8a8c868b26d60a90686b95f8aa61 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -108,9 +108,9 @@ void rrc_gNB_generate_RRCSetup( const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP, - OCTET_STRING_t *masterCellGroup_from_DU, - NR_ServingCellConfigCommon_t *scc, - const int CC_id); + const uint8_t *masterCellGroup, + int masterCellGroup_len, + NR_ServingCellConfigCommon_t *scc); int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m); @@ -120,7 +120,7 @@ rrc_gNB_generate_SecurityModeCommand( rrc_gNB_ue_context_t *const ue_context_pP ); -uint8_t + uint8_t rrc_gNB_get_next_transaction_identifier( module_id_t gnb_mod_idP ); @@ -174,19 +174,6 @@ int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, const int dl_bwp_id, const int ul_bwp_id); -int8_t nr_mac_rrc_data_ind( - const module_id_t module_idP, - const int CC_id, - const frame_t frameP, - const sub_frame_t sub_frameP, - const int UE_id, - const rnti_t rntiP, - const rb_id_t srb_idP, - const uint8_t *sduP, - const sdu_size_t sdu_lenP, - const boolean_t brOption -); - int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP, protocol_ctxt_t *const ctxt_pP, const int dl_bwp_id, @@ -195,8 +182,8 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, const uint8_t *buffer, int buffer_length, - OCTET_STRING_t *du_to_cu_rrc_container, - const int CC_id); + const uint8_t *du_to_cu_rrc_container, + int du_to_cu_rrc_container_length); void rrc_gNB_generate_dedicatedRRCReconfiguration_release( @@ -209,7 +196,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( void rrc_gNB_generate_dedicatedRRCReconfiguration( const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP); + rrc_gNB_ue_context_t *ue_context_pP, + NR_CellGroupConfig_t *cell_groupConfig_from_DU); rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, const NR_SRB_ToAddModList_t * const srb2add_listP, @@ -218,16 +206,15 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); -boolean_t nr_rrc_pdcp_config_asn1_req( - const protocol_ctxt_t *const ctxt_pP, - NR_SRB_ToAddModList_t *const srb2add_list, - NR_DRB_ToAddModList_t *const drb2add_list, - NR_DRB_ToReleaseList_t *const drb2release_list, - const uint8_t security_modeP, - uint8_t *const kRRCenc, - uint8_t *const kRRCint, - uint8_t *const kUPenc, - uint8_t *const kUPint - ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 - ,rb_id_t *const defaultDRB, - struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); +bool nr_rrc_pdcp_config_asn1_req(const protocol_ctxt_t *const ctxt_pP, + NR_SRB_ToAddModList_t *const srb2add_list, + NR_DRB_ToAddModList_t *const drb2add_list, + NR_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc, + uint8_t *const kUPint, + LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9, + rb_id_t *const defaultDRB, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index d03e00f8c6b1146bd037e67b6b32a735fdd25e84..8be829f51fbc8c1c8bc4019fd07b78149900bbe2 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -99,6 +99,7 @@ #include <openair2/X2AP/x2ap_eNB.h> #include <openair3/ocp-gtpu/gtp_itf.h> #include <openair2/RRC/NR/nr_rrc_proto.h> +#include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "BIT_STRING.h" #include "assertions.h" @@ -115,16 +116,16 @@ uint8_t first_rrcreconfiguration = 0; ///---------------------------------------------------------------------------------------------------------------/// ///---------------------------------------------------------------------------------------------------------------/// -boolean_t DURecvCb( protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) { +bool DURecvCb(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id) { // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue mem_block_t *sdu=get_free_mem_block(sdu_buffer_sizeP, __func__); memcpy(sdu->data, sdu_buffer_pP, sdu_buffer_sizeP); @@ -164,9 +165,8 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration LOG_I(NR_RRC,"Done init_NR_SI\n"); - if (NODE_IS_MONOLITHIC(rrc->node_type)){ + if (NODE_IS_MONOLITHIC(rrc->node_type) || NODE_IS_DU(rrc->node_type)){ rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -196,21 +196,41 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration } } +static void rrc_gNB_mac_rrc_init(gNB_RRC_INST *rrc) +{ + switch (rrc->node_type) { + case ngran_gNB_CU: + mac_rrc_dl_f1ap_init(&rrc->mac_rrc); + break; + case ngran_gNB_DU: + /* silently drop this, as we currently still need the RRC at the DU. As + * soon as this is not the case anymore, we can add the AssertFatal() */ + //AssertFatal(1==0,"nothing to do for DU\n"); + break; + case ngran_gNB: + mac_rrc_dl_direct_init(&rrc->mac_rrc); + break; + default: + AssertFatal(0 == 1, "Unknown node type %d\n", rrc->node_type); + break; + } +} + char openair_rrc_gNB_configuration(const module_id_t gnb_mod_idP, gNB_RrcConfigurationReq *configuration) { - protocol_ctxt_t ctxt; + protocol_ctxt_t ctxt = { 0 }; gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP]; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, gnb_mod_idP, GNB_FLAG_YES, NOT_A_RNTI, 0, 0,gnb_mod_idP); LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_FMT" Init...\n", PROTOCOL_NR_RRC_CTXT_ARGS(&ctxt)); - AssertFatal(rrc != NULL, "RC.nrrrc not initialized!"); AssertFatal(NUMBER_OF_UE_MAX < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow"); AssertFatal(configuration!=NULL,"configuration input is null\n"); rrc->module_id = gnb_mod_idP; rrc->Nb_ue = 0; rrc->carrier.Srb0.Active = 0; - nr_uid_linear_allocator_init(&rrc->uid_allocator); + rrc_gNB_mac_rrc_init(rrc); + uid_linear_allocator_init(&rrc->uid_allocator); RB_INIT(&rrc->rrc_ue_head); rrc->initial_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); rrc->s1ap_id2_s1ap_ids = hashtable_create (NUMBER_OF_UE_MAX * 2, NULL, NULL); @@ -276,7 +296,6 @@ void apply_macrlc_config(gNB_RRC_INST *rrc, NR_CellGroupConfig_t *cgc = get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup : NULL; rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -320,119 +339,52 @@ void rrc_gNB_generate_RRCSetup( const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP, - OCTET_STRING_t *masterCellGroup_from_DU, - NR_ServingCellConfigCommon_t *scc, - const int CC_id -) + const uint8_t *masterCellGroup, + int masterCellGroup_len, + NR_ServingCellConfigCommon_t *scc) //----------------------------------------------------------------------------- { - LOG_D(NR_RRC, "rrc_gNB_generate_RRCSetup \n"); - MessageDef *message_p; + LOG_I(NR_RRC, "rrc_gNB_generate_RRCSetup for RNTI %04x\n", ctxt_pP->rnti); // T(T_GNB_RRC_SETUP, // T_INT(ctxt_pP->module_id), // T_INT(ctxt_pP->frame), // T_INT(ctxt_pP->subframe), // T_INT(ctxt_pP->rnti)); + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - NR_ServingCellConfig_t *servingcellconfigdedicated = rrc->configuration.scd; - int16_t ret = do_RRCSetup(ue_context_pP, - (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, - rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), - masterCellGroup_from_DU, - scc,servingcellconfigdedicated,&rrc->configuration); - - AssertFatal(ret>0,"Error generating RRCSetup for RRCSetupRequest\n"); - - ue_p->Srb0.Tx_buffer.payload_size = ret; + const NR_ServingCellConfig_t *sccd = rrc->configuration.scd; + ue_p->Srb0.Tx_buffer.payload_size = do_RRCSetup(ue_context_pP, + (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, + rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), + masterCellGroup, + masterCellGroup_len, + scc, + sccd, + &rrc->configuration); LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)(ue_p->Srb0.Tx_buffer.Payload), ue_p->Srb0.Tx_buffer.payload_size, "[MSG] RRC Setup\n"); - switch (rrc->node_type) { - case ngran_gNB_CU: - // create an ITTI message - /* TODO: F1 IDs ar missing in RRC */ - nr_rrc_pdcp_config_asn1_req(ctxt_pP, - ue_context_pP->ue_context.SRB_configList, - NULL, - NULL, - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_DL_RRC_MESSAGE); - F1AP_DL_RRC_MESSAGE (message_p).rrc_container = (uint8_t *)ue_p->Srb0.Tx_buffer.Payload; - F1AP_DL_RRC_MESSAGE (message_p).rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size; - F1AP_DL_RRC_MESSAGE (message_p).gNB_CU_ue_id = 0; - F1AP_DL_RRC_MESSAGE (message_p).gNB_DU_ue_id = 0; - F1AP_DL_RRC_MESSAGE (message_p).old_gNB_DU_ue_id = 0xFFFFFFFF; // unknown - F1AP_DL_RRC_MESSAGE (message_p).rnti = ue_p->rnti; - F1AP_DL_RRC_MESSAGE (message_p).srb_id = CCCH; - F1AP_DL_RRC_MESSAGE (message_p).execute_duplication = 1; - F1AP_DL_RRC_MESSAGE (message_p).RAT_frequency_priority_information.en_dc = 0; - itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); - LOG_D(NR_RRC, "Send F1AP_DL_RRC_MESSAGE with ITTI\n"); - - break; - - case ngran_gNB_DU: - // nothing to do for DU - AssertFatal(1==0,"nothing to do for DU\n"); - break; - - case ngran_gNB: - { - // rrc_mac_config_req_gNB - -#ifdef ITTI_SIM - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_p->Srb0.Tx_buffer.payload_size); - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, - ue_p->Srb0.Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND); - GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else - LOG_D(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" RRC_gNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - LOG_I(NR_RRC, - PROTOCOL_NR_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCSetup (bytes %d)\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_p->Srb0.Tx_buffer.payload_size); - // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE - ue_context_pP->ue_context.ue_release_timer = 1; - // remove UE after 10 frames after RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres = 1000; - /* init timers */ - // ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; - - // configure MAC - - apply_macrlc_config(rrc,ue_context_pP,ctxt_pP); - - apply_pdcp_config(ue_context_pP,ctxt_pP); -#endif - } - break; + // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE + ue_context_pP->ue_context.ue_release_timer = 1; + // remove UE after 10 frames after RRCConnectionRelease is triggered + ue_context_pP->ue_context.ue_release_timer_thres = 1000; - default: - LOG_W(NR_RRC, "Unknown node type %d\n", rrc->node_type); - break; - } + /* TODO: this should go through the E1 interface */ + apply_pdcp_config(ue_context_pP,ctxt_pP); + + f1ap_dl_rrc_message_t dl_rrc = { + .old_gNB_DU_ue_id = 0xFFFFFF, + .rrc_container = (uint8_t *)ue_p->Srb0.Tx_buffer.Payload, + .rrc_container_length = ue_p->Srb0.Tx_buffer.payload_size, + .rnti = ue_p->rnti, + .srb_id = CCCH + }; + rrc->mac_rrc.dl_rrc_message_transfer(ctxt_pP->module_id, &dl_rrc); } //----------------------------------------------------------------------------- @@ -446,8 +398,8 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( LOG_I(NR_RRC, "generate RRCSetup for RRCReestablishmentRequest \n"); rrc_gNB_ue_context_t *ue_context_pP = NULL; gNB_RRC_INST *rrc_instance_p = RC.nrrrc[ctxt_pP->module_id]; - NR_ServingCellConfigCommon_t *scc=rrc_instance_p->carrier.servingcellconfigcommon; - NR_ServingCellConfig_t *servingcellconfigdedicated = rrc_instance_p->configuration.scd; + const NR_ServingCellConfigCommon_t *scc=rrc_instance_p->carrier.servingcellconfigcommon; + const NR_ServingCellConfig_t *sccd = rrc_instance_p->configuration.scd; ue_context_pP = rrc_gNB_get_next_free_ue_context(ctxt_pP, rrc_instance_p, 0); @@ -456,7 +408,10 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( (uint8_t *) ue_p->Srb0.Tx_buffer.Payload, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), NULL, - scc,servingcellconfigdedicated,&rrc_instance_p->configuration); + 0, + scc, + sccd, + &rrc_instance_p->configuration); AssertFatal(ret>0,"Error generating RRCSetup for RRCReestablishmentRequest\n"); @@ -472,7 +427,6 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); rrc_mac_config_req_gNB(rrc_instance_p->module_id, - rrc_instance_p->configuration.ssb_SubcarrierOffset, rrc_instance_p->configuration.pdsch_AntennaPorts, rrc_instance_p->configuration.pusch_AntennaPorts, rrc_instance_p->configuration.sib1_tda, @@ -494,25 +448,12 @@ rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest( ue_context_pP->ue_context.ue_release_timer_thres = 1000; /* init timers */ // ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, - ue_p->Srb0.Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND); - GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#endif } void rrc_gNB_generate_RRCReject( const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - const int CC_id -) + rrc_gNB_ue_context_t *const ue_context_pP) //----------------------------------------------------------------------------- { LOG_I(NR_RRC, "rrc_gNB_generate_RRCReject \n"); @@ -554,16 +495,8 @@ rrc_gNB_generate_RRCReject( case ngran_gNB: { -#ifdef ITTI_SIM - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, - ue_p->Srb0.Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t*)ue_p->Srb0.Tx_buffer.Payload, ue_p->Srb0.Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_CCCH_DATA_IND); - GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_CCCH_DATA_IND (message_p).size = ue_p->Srb0.Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#endif + // NOTE: there was ITTI_SIM which has been removed. This case is maybe + // not necessary anymore // rrc_mac_config_req_gNB } break; @@ -771,17 +704,6 @@ rrc_gNB_generate_defaultRRCReconfiguration( case ngran_gNB: { -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, @@ -798,7 +720,6 @@ rrc_gNB_generate_defaultRRCReconfiguration( buffer, PDCP_TRANSMISSION_MODE_CONTROL); // rrc_pdcp_config_asn1_req -#endif // rrc_rlc_config_asn1_req } break; @@ -808,8 +729,8 @@ rrc_gNB_generate_defaultRRCReconfiguration( } if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { + gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -838,7 +759,8 @@ rrc_gNB_generate_defaultRRCReconfiguration( void rrc_gNB_generate_dedicatedRRCReconfiguration( const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP + rrc_gNB_ue_context_t *ue_context_pP, + NR_CellGroupConfig_t *cell_groupConfig_from_DU ) //----------------------------------------------------------------------------- { @@ -861,7 +783,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( uint8_t drb_id_to_setup_start = 1; uint8_t nb_drb_to_setup = 0; long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) - NR_CellGroupConfig_t *cellGroupConfig; + NR_CellGroupConfig_t *cellGroupConfig = NULL; uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); @@ -918,7 +840,7 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( sdap_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent; sdap_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent; } - sdap_config->defaultDRB = TRUE; + sdap_config->defaultDRB = true; sdap_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd)); memset(sdap_config->mappedQoS_FlowsToAdd, 0, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd)); @@ -1017,9 +939,17 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( } memset(buffer, 0, sizeof(buffer)); - cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); + if(cell_groupConfig_from_DU == NULL){ + cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); + // FIXME: fill_mastercellGroupConfig() won't fill the right priorities or + // bearer IDs for the DRBs + fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); + } + else{ + LOG_I(NR_RRC, "Master cell group originating from the DU \n"); + cellGroupConfig = cell_groupConfig_from_DU; + } - fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer), xid, *SRB_configList2, @@ -1052,17 +982,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else nr_rrc_data_req( ctxt_pP, DCCH, @@ -1071,11 +990,9 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif if (NODE_IS_DU(rrc->node_type) || NODE_IS_MONOLITHIC(rrc->node_type)) { rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -1251,17 +1168,6 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB_SIM, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else nr_rrc_data_req( ctxt_pP, DCCH, @@ -1270,7 +1176,6 @@ rrc_gNB_modify_dedicatedRRCReconfiguration( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup && @@ -1364,17 +1269,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else nr_rrc_data_req( ctxt_pP, DCCH, @@ -1383,7 +1277,6 @@ rrc_gNB_generate_dedicatedRRCReconfiguration_release( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { uint32_t delay_ms = ue_context_pP->ue_context.masterCellGroup && @@ -1420,7 +1313,6 @@ rrc_gNB_process_RRCReconfigurationComplete( NR_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; NR_DRB_Identity_t *drb_id_p = NULL; // uint8_t nr_DRB2LCHAN[8]; - gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; ue_context_pP->ue_context.ue_reestablishment_timer = 0; @@ -1442,7 +1334,6 @@ rrc_gNB_process_RRCReconfigurationComplete( &kRRCint); /* Refresh SRBs/DRBs */ -#ifndef ITTI_SIM LOG_D(NR_RRC,"Configuring PDCP DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti); nr_rrc_pdcp_config_asn1_req(ctxt_pP, @@ -1459,7 +1350,6 @@ rrc_gNB_process_RRCReconfigurationComplete( NULL, get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); /* Refresh SRBs/DRBs */ - if (!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { LOG_D(NR_RRC,"Configuring RLC DRBs/SRBs for UE %x\n",ue_context_pP->ue_context.rnti); nr_rrc_rlc_config_asn1_req(ctxt_pP, @@ -1469,50 +1359,6 @@ rrc_gNB_process_RRCReconfigurationComplete( NULL, get_softmodem_params()->sa ? ue_context_pP->ue_context.masterCellGroup->rlc_BearerToAddModList : NULL); } - else if(SRB_configList!=NULL || DRB_configList!=NULL){ - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ); - f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_SETUP_REQ (message_p); - req->gNB_CU_ue_id = 0; - req->gNB_DU_ue_id = 0; - req->rnti = ue_context_pP->ue_context.rnti; - req->mcc = rrc->configuration.mcc[0]; - req->mnc = rrc->configuration.mnc[0]; - req->mnc_digit_length = rrc->configuration.mnc_digit_length[0]; - req->nr_cellid = rrc->nr_cellid; - if(SRB_configList!=NULL){ - req->srbs_to_be_setup = malloc(SRB_configList->list.count*sizeof(f1ap_srb_to_be_setup_t)); - req->srbs_to_be_setup_length = SRB_configList->list.count; - f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup; - for (int i = 0; i < SRB_configList->list.count; i++){ - if(SRB_configList->list.array[i]->srb_Identity > 1){ - SRBs[i].srb_id = SRB_configList->list.array[i]->srb_Identity; - SRBs[i].lcid = SRB_configList->list.array[i]->srb_Identity; - } - } - } - if(DRB_configList!=NULL){ - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; - memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); - req->drbs_to_be_setup = malloc(DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t)); - req->drbs_to_be_setup_length = DRB_configList->list.count; - f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup; - LOG_I(RRC, "Length of DRB list:%d, %d \n", DRB_configList->list.count, req->drbs_to_be_setup_length); - for (int i = 0; i < DRB_configList->list.count; i++){ - DRBs[i].drb_id = DRB_configList->list.array[i]->drb_Identity; - DRBs[i].rlc_mode = RLC_MODE_AM; - DRBs[i].up_ul_tnl[0].tl_address = inet_addr(rrc->eth_params_s.my_addr); - DRBs[i].up_ul_tnl[0].port=rrc->eth_params_s.my_portd; - DRBs[i].up_ul_tnl_length = 1; - DRBs[i].up_dl_tnl[0].tl_address = inet_addr(rrc->eth_params_s.remote_addr); - DRBs[i].up_dl_tnl[0].port=rrc->eth_params_s.remote_portd; - DRBs[i].up_dl_tnl_length = 1; - } - LOG_I(RRC, "Send F1AP_UE_CONTEXT_SETUP_REQ with ITTI\n"); - } - itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); - } -#endif /* Set the SRB active in UE context */ if (SRB_configList != NULL) { @@ -1674,18 +1520,6 @@ rrc_gNB_generate_RRCReestablishment( rnti); } #endif -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, ue_context->Srb0.Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t *) ue_context->Srb0.Tx_buffer.Payload, ue_context->Srb0.Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = ue_context->Srb0.Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#endif - } //----------------------------------------------------------------------------- @@ -1806,15 +1640,16 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( } } - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; /* Save e RAB information for later */ - memset(&create_tunnel_req, 0, sizeof(create_tunnel_req)); for ( j = 0, i = 0; i < NB_RB_MAX; i++) { if (ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_DONE) { create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pduSession[i].param.pdusession_id; create_tunnel_req.incoming_rb_id[j] = i+1; create_tunnel_req.outgoing_teid[j] = ue_context_pP->ue_context.pduSession[i].param.gtp_teid; + // to be developped, use the first QFI only + create_tunnel_req.outgoing_qfi[j] = ue_context_pP->ue_context.pduSession[i].param.qos[0].qfi; memcpy(create_tunnel_req.dst_addr[j].buffer, ue_context_pP->ue_context.pduSession[i].param.upf_addr.buffer, sizeof(uint8_t)*20); @@ -1865,7 +1700,7 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( ue_context_pP->ue_context.rnti = ctxt_pP->rnti; if (AMF_MODE_ENABLED) { - uint8_t send_security_mode_command = FALSE; + uint8_t send_security_mode_command = false; nr_rrc_pdcp_config_security( ctxt_pP, ue_context_pP, @@ -1922,17 +1757,6 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( LOG_D(NR_RRC, "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_gNB_mui, ctxt_pP->module_id, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else nr_rrc_data_req( ctxt_pP, DCCH, @@ -1941,7 +1765,6 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif } if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { @@ -1988,7 +1811,7 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP NULL, NULL, NULL, - NULL, + ue_context_pP, NULL, NULL, NULL, @@ -1996,7 +1819,6 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP gNB_RrcConfigurationReq *configuration = &RC.nrrrc[ctxt_pP->module_id]->configuration; rrc_mac_config_req_gNB(ctxt_pP->module_id, - configuration->ssb_SubcarrierOffset, configuration->pdsch_AntennaPorts, configuration->pusch_AntennaPorts, configuration->sib1_tda, @@ -2036,8 +1858,8 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, const uint8_t *buffer, int buffer_length, - OCTET_STRING_t *du_to_cu_rrc_container, - const int CC_id) + const uint8_t *du_to_cu_rrc_container, + int du_to_cu_rrc_container_len) { module_id_t Idx; asn_dec_rval_t dec_rval; @@ -2047,22 +1869,16 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, NR_RRCSetupRequest_IEs_t *rrcSetupRequest = NULL; NR_RRCReestablishmentRequest_IEs_t rrcReestablishmentRequest; uint64_t random_value = 0; - int i; - dec_rval = uper_decode( NULL, - &asn_DEF_NR_UL_CCCH_Message, - (void **)&ul_ccch_msg, - (uint8_t *) buffer, - 100, - 0, - 0); + LOG_I(NR_RRC, "Decoding CCCH: RNTI %04x, inst %ld, payload_size %d\n", ctxt_pP->rnti, ctxt_pP->instance, buffer_length); + dec_rval = uper_decode(NULL, &asn_DEF_NR_UL_CCCH_Message, (void **) &ul_ccch_msg, buffer, buffer_length, 0, 0); - if (dec_rval.consumed == 0) { - /* TODO */ - LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - return -1; - } + if (dec_rval.code != RC_OK || dec_rval.consumed == 0) { + LOG_E(NR_RRC, + PROTOCOL_NR_RRC_CTXT_UE_FMT" FATAL Error in receiving CCCH\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); + return -1; + } if (ul_ccch_msg->message.present == NR_UL_CCCH_MessageType_PR_c1) { switch (ul_ccch_msg->message.choice.c1->present) { @@ -2153,7 +1969,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, } if (ue_context_p != NULL) { - ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = TRUE; + ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence = true; ue_context_p->ue_context.ng_5G_S_TMSI_Part1 = s_tmsi_part1; } } @@ -2168,8 +1984,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRCSetupRequest without random UE identity or S-TMSI not supported, let's reject the UE\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); rrc_gNB_generate_RRCReject(ctxt_pP, - rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), - CC_id); + rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti)); break; } @@ -2178,8 +1993,8 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, rrc_gNB_generate_RRCSetup(ctxt_pP, rrc_gNB_get_ue_context(gnb_rrc_inst, ctxt_pP->rnti), du_to_cu_rrc_container, - gnb_rrc_inst->carrier.servingcellconfigcommon, - CC_id); + du_to_cu_rrc_container_len, + gnb_rrc_inst->carrier.servingcellconfigcommon); } break; @@ -2211,13 +2026,13 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), rrcReestablishmentRequest.ue_Identity.physCellId, RC.nrrrc[ctxt_pP->module_id]->carrier.physCellId); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); break; } LOG_D(NR_RRC, "physCellId is %ld\n", rrcReestablishmentRequest.ue_Identity.physCellId); - for (i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) { + for (int i = 0; i < rrcReestablishmentRequest.ue_Identity.shortMAC_I.size; i++) { LOG_D(NR_RRC, "rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[%d] = %x\n", i, rrcReestablishmentRequest.ue_Identity.shortMAC_I.buf[i]); } @@ -2228,7 +2043,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest c_RNTI range error, fallback to RRC establishment\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); break; } @@ -2240,7 +2055,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); break; } #if(0) @@ -2251,14 +2066,14 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" NR_RRCReestablishmentRequest without UE_id(MAC) rnti %x, fallback to RRC establishment\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); break; } //previous rnti rnti_t previous_rnti = 0; - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (reestablish_rnti_map[i][1] == c_rnti) { previous_rnti = reestablish_rnti_map[i][0]; break; @@ -2272,7 +2087,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" RRCReestablishmentRequest without UE_id(MAC) previous rnti %x, fallback to RRC establishment\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP),previous_rnti); - rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, CC_id); + rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(ctxt_pP, 0); break; } } @@ -2326,7 +2141,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, ue_context_p->ue_context.reestablishment_xid = -1; // insert C-RNTI to map - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (reestablish_rnti_map[i][0] == 0) { reestablish_rnti_map[i][0] = ctxt_pP->rnti; reestablish_rnti_map[i][1] = c_rnti; @@ -2342,7 +2157,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, rrcReestablishmentRequest.ue_Identity.physCellId, ue_context_p->ue_context.reestablishment_cause); - ue_context_p->ue_context.primaryCC_id = CC_id; + ue_context_p->ue_context.primaryCC_id = 0; //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; Idx = DCCH; // SRB1 @@ -2364,7 +2179,7 @@ int nr_rrc_gNB_decode_ccch(protocol_ctxt_t *const ctxt_pP, &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); - rrc_gNB_generate_RRCReestablishment(ctxt_pP, ue_context_p, CC_id); + rrc_gNB_generate_RRCReestablishment(ctxt_pP, ue_context_p, 0); LOG_I(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n", PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), @@ -2630,7 +2445,7 @@ rrc_gNB_decode_dcch( fiveg_s_TMSI, fiveg_s_TMSI >> 38, fiveg_s_TMSI >> 38, (fiveg_s_TMSI >> 32) & 0x3F, (fiveg_s_TMSI >> 32) & 0x3F, (uint32_t)fiveg_s_TMSI); - if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) { + if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == true) { ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_set_id = fiveg_s_TMSI >> 38; ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.amf_pointer = (fiveg_s_TMSI >> 32) & 0x3F; ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi = (uint32_t)fiveg_s_TMSI; @@ -2814,12 +2629,75 @@ rrc_gNB_decode_dcch( ul_dcch_msg); } - if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { - rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p); - } else { - rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + if(!NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)){ + if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { + rrc_gNB_generate_dedicatedRRCReconfiguration(ctxt_pP, ue_context_p, NULL); + } else { + rrc_gNB_generate_defaultRRCReconfiguration(ctxt_pP, ue_context_p); + } + } + else{ + /*Generate a UE context setup request message towards the DU to provide the UE + *capability info and get the updates on master cell group config from the DU*/ + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ); + f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_SETUP_REQ (message_p); + //UE_IDs will be extracted from F1AP layer + req->gNB_CU_ue_id = 0; + req->gNB_DU_ue_id = 0; + req->rnti = ue_context_p->ue_context.rnti; + req->mcc = RC.nrrrc[ctxt_pP->module_id]->configuration.mcc[0]; + req->mnc = RC.nrrrc[ctxt_pP->module_id]->configuration.mnc[0]; + req->mnc_digit_length = RC.nrrrc[ctxt_pP->module_id]->configuration.mnc_digit_length[0]; + req->nr_cellid = RC.nrrrc[ctxt_pP->module_id]->nr_cellid; + + if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { + /*Instruction towards the DU for SRB2 configuration*/ + req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t)); + req->srbs_to_be_setup_length = 1; + f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup; + SRBs[0].srb_id = 2; + SRBs[0].lcid = 2; + + /*Instruction towards the DU for DRB configuration and tunnel creation*/ + req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)); + req->drbs_to_be_setup_length = 1; + f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup; + LOG_I(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length); + DRBs[0].drb_id = 1; + DRBs[0].rlc_mode = RLC_MODE_AM; + DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt_pP->module_id]->eth_params_s.my_addr); + DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt_pP->module_id]->eth_params_s.my_portd; + DRBs[0].up_ul_tnl_length = 1; + DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt_pP->module_id]->eth_params_s.remote_addr); + DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt_pP->module_id]->eth_params_s.remote_portd; + DRBs[0].up_dl_tnl_length = 1; + } + if( ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present == + NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation ) { + struct NR_UE_CapabilityRAT_ContainerList *ue_CapabilityRAT_ContainerList = + ul_dcch_msg->message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList; + if(ue_CapabilityRAT_ContainerList!=NULL){ + LOG_I(NR_RRC, "ue_CapabilityRAT_ContainerList is present \n"); + req->cu_to_du_rrc_information = calloc(1,sizeof(cu_to_du_rrc_information_t)); + req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList = calloc(1,4096); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_CapabilityRAT_ContainerList, + NULL, + ue_CapabilityRAT_ContainerList, + req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, + 4096); + AssertFatal (enc_rval.encoded > 0, "ASN1 ue_CapabilityRAT_ContainerList encoding failed (%s, %jd)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length = (enc_rval.encoded+7)>>3; + } + else{ + LOG_I(NR_RRC, "ue_CapabilityRAT_ContainerList is not present \n"); + } + } + itti_send_msg_to_task (TASK_CU_F1, ctxt_pP->module_id, message_p); } + break; case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: @@ -2931,11 +2809,8 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { memset(mib->message.choice.mib,0,sizeof(struct NR_MIB)); memcpy(mib->message.choice.mib, mib_DU->message.choice.mib, sizeof(struct NR_MIB)); - rrc->carrier.SIB1 = malloc(f1_setup_req->sib1_length[i]); - rrc->carrier.sizeof_SIB1 = f1_setup_req->sib1_length[i]; - memcpy((void *)rrc->carrier.SIB1,f1_setup_req->sib1[i],f1_setup_req->sib1_length[i]); dec_rval = uper_decode_complete(NULL, - &asn_DEF_NR_BCCH_DL_SCH_Message, + &asn_DEF_NR_SIB1, //&asn_DEF_NR_BCCH_DL_SCH_Message, (void **)&rrc->carrier.siblock1_DU, f1_setup_req->sib1[i], f1_setup_req->sib1_length[i]); @@ -2945,12 +2820,12 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { dec_rval.consumed ); // Parse message and extract SystemInformationBlockType1 field - NR_BCCH_DL_SCH_Message_t *bcch_message = rrc->carrier.siblock1_DU; - AssertFatal(bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1, - "bcch_message->message.present != NR_BCCH_DL_SCH_MessageType_PR_c1\n"); - AssertFatal(bcch_message->message.choice.c1->present == NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1, - "bcch_message->message.choice.c1->present != NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1\n"); - rrc->carrier.sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1; + rrc->carrier.sib1 = rrc->carrier.siblock1_DU; + if ( LOG_DEBUGFLAG(DEBUG_ASN1)){ + LOG_I(NR_RRC, "Printing received SIB1 container inside F1 setup request message:\n"); + xer_fprint(stdout, &asn_DEF_NR_SIB1,(void *)rrc->carrier.sib1); + } + rrc->carrier.physCellId = f1_setup_req->cell[i].nr_pci; F1AP_GNB_CU_CONFIGURATION_UPDATE (msg_p2).gNB_CU_name = rrc->node_name; @@ -2994,6 +2869,38 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *f1_setup_req) { }//for (int i=0;i<f1_setup_req->num_cells_available;i++) } +void rrc_gNB_process_initial_ul_rrc_message(const f1ap_initial_ul_rrc_message_t *ul_rrc) +{ + // first get RRC instance (note, no the ITTI instance) + module_id_t i = 0; + for (i=0; i < RC.nb_nr_inst; i++) { + gNB_RRC_INST *rrc = RC.nrrrc[i]; + if (rrc->nr_cellid == ul_rrc->nr_cellid) + break; + } + //AssertFatal(i != RC.nb_nr_inst, "Cell_id not found\n"); + // TODO REMOVE_DU_RRC in monolithic mode, the MAC does not have the + // nr_cellid. Thus, the above check would fail. For the time being, just put + // a warning, as we handle one DU only anyway + if (i == RC.nb_nr_inst) { + i = 0; + LOG_W(RRC, "initial UL RRC message nr_cellid %ld does not match RRC's %ld\n", ul_rrc->nr_cellid, RC.nrrrc[0]->nr_cellid); + } + protocol_ctxt_t ctxt = { 0 }; + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, i, GNB_FLAG_YES, ul_rrc->crnti, 0, 0); + + nr_rrc_gNB_decode_ccch(&ctxt, + ul_rrc->rrc_container, + ul_rrc->rrc_container_length, + ul_rrc->du2cu_rrc_container, + ul_rrc->du2cu_rrc_container_length); + + if (ul_rrc->rrc_container) + free(ul_rrc->rrc_container); + if (ul_rrc->du2cu_rrc_container) + free(ul_rrc->du2cu_rrc_container); +} + void rrc_gNB_process_release_request(const module_id_t gnb_mod_idP, x2ap_ENDC_sgnb_release_request_t *m) { gNB_RRC_INST *rrc = RC.nrrrc[gnb_mod_idP]; @@ -3008,77 +2915,19 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC static int rrc_process_DU_DL(MessageDef *msg_p, const char *msg_name, instance_t instance) { NRDuDlReq_t * req=&NRDuDlReq(msg_p); - protocol_ctxt_t ctxt; - ctxt.rnti = req->rnti; - ctxt.module_id = instance; - ctxt.instance = instance; - ctxt.enb_flag = 1; + protocol_ctxt_t ctxt = { + .rnti = req->rnti, + .module_id = instance, + .instance = instance, + .enb_flag = 1, + .eNB_index = instance + }; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rnti); if (req->srb_id == 0) { - NR_DL_CCCH_Message_t *dl_ccch_msg=NULL; - asn_dec_rval_t dec_rval; - dec_rval = uper_decode(NULL, - &asn_DEF_NR_DL_CCCH_Message, - (void **)&dl_ccch_msg, - req->buf->data, - req->buf->size,0,0); - AssertFatal(dec_rval.code == RC_OK, "could not decode F1AP message\n"); - - switch (dl_ccch_msg->message.choice.c1->present) { - case NR_DL_CCCH_MessageType__c1_PR_NOTHING: - LOG_I(F1AP,"Received PR_NOTHING on DL-CCCH-Message\n"); - break; - - case NR_DL_CCCH_MessageType__c1_PR_rrcReject: - LOG_I(F1AP,"Logical Channel DL-CCCH (SRB0), Received RRCReject\n"); - break; - - case NR_DL_CCCH_MessageType__c1_PR_rrcSetup: { - LOG_I(F1AP, "Logical Channel DL-CCCH (SRB0), Received RRCSetup RNTI %x\n", - req->rnti); - // Get configuration - NR_RRCSetup_t *rrcSetup = dl_ccch_msg->message.choice.c1->choice.rrcSetup; - AssertFatal(rrcSetup!=NULL, "rrcSetup is null\n"); - NR_RRCSetup_IEs_t *rrcSetup_ies = rrcSetup->criticalExtensions.choice.rrcSetup; - ue_context_p->ue_context.SRB_configList = rrcSetup_ies->radioBearerConfig.srb_ToAddModList; - AssertFatal(rrcSetup_ies->masterCellGroup.buf!=NULL,"masterCellGroup is null\n"); - asn_dec_rval_t dec_rval; - dec_rval = uper_decode(NULL, - &asn_DEF_NR_CellGroupConfig, - (void **)&ue_context_p->ue_context.masterCellGroup, - rrcSetup_ies->masterCellGroup.buf, - rrcSetup_ies->masterCellGroup.size,0,0); - AssertFatal(dec_rval.code == RC_OK, "could not decode masterCellGroup\n"); - apply_macrlc_config(rrc,ue_context_p,&ctxt); - gNB_RRC_UE_t *ue_p = &ue_context_p->ue_context; - AssertFatal(ue_p->Srb0.Active == 1,"SRB0 is not active\n"); - memcpy((void *)ue_p->Srb0.Tx_buffer.Payload, - (void *)req->buf->data, - req->buf->size); // ie->value.choice.RRCContainer.size - ue_p->Srb0.Tx_buffer.payload_size = req->buf->size; - break; - } // case - - case NR_DL_CCCH_MessageType__c1_PR_spare2: - LOG_I(F1AP, - "Logical Channel DL-CCCH (SRB0), Received spare2\n"); - break; - - case NR_DL_CCCH_MessageType__c1_PR_spare1: - LOG_I(F1AP, - "Logical Channel DL-CCCH (SRB0), Received spare1\n"); - break; - - default: - AssertFatal(1==0, - "Unknown message\n"); - break; - }// switch case - - return(0); + AssertFatal(0 == 1, "should pass through dl_rrc_message()\n"); } else if (req->srb_id == 1) { NR_DL_DCCH_Message_t *dl_dcch_msg=NULL; asn_dec_rval_t dec_rval; @@ -3213,7 +3062,6 @@ static int rrc_process_DU_DL(MessageDef *msg_p, const char *msg_name, instance_ LOG_I(F1AP, "Received DL RRC Transfer on srb_id %ld\n", req->srb_id); // rlc_op_status_t rlc_status; - // boolean_t ret = TRUE; //LOG_I(F1AP, "PRRCContainer size %lu:", ie->value.choice.RRCContainer.size); //for (int i = 0; i < ie->value.choice.RRCContainer.size; i++) @@ -3238,23 +3086,23 @@ static int rrc_process_DU_DL(MessageDef *msg_p, const char *msg_name, instance_ // switch (rlc_status) { // case RLC_OP_STATUS_OK: // //LOG_I(F1AP, "Data sending request over RLC succeeded!\n"); - // ret=TRUE; + // ret=true; // break; // case RLC_OP_STATUS_BAD_PARAMETER: // LOG_W(F1AP, "Data sending request over RLC failed with 'Bad Parameter' reason!\n"); - // ret= FALSE; + // ret= false; // break; // case RLC_OP_STATUS_INTERNAL_ERROR: // LOG_W(F1AP, "Data sending request over RLC failed with 'Internal Error' reason!\n"); - // ret= FALSE; + // ret= false; // break; // case RLC_OP_STATUS_OUT_OF_RESSOURCES: // LOG_W(F1AP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); - // ret= FALSE; + // ret= false; // break; // default: // LOG_W(F1AP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); - // ret= FALSE; + // ret= false; // break; // } // switch case // return ret; @@ -3264,11 +3112,13 @@ return 0; static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const char *msg_name, instance_t instance){ f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_SETUP_REQ(msg_p); - protocol_ctxt_t ctxt; - ctxt.rnti = req->rnti; - ctxt.module_id = instance; - ctxt.instance = instance; - ctxt.enb_flag = 1; + protocol_ctxt_t ctxt = { + .rnti = req->rnti, + .module_id = instance, + .instance = instance, + .enb_flag = 1, + .eNB_index = instance + }; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id]; struct rrc_gNB_ue_context_s *ue_context_p = @@ -3278,6 +3128,94 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(message_p); uint32_t incoming_teid = 0; + if(req->cu_to_du_rrc_information!=NULL){ + if(req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){ + LOG_I(NR_RRC, "Length of ue_CapabilityRAT_ContainerList is: %d \n", (int) req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); + struct NR_UE_CapabilityRAT_ContainerList *ue_CapabilityRAT_ContainerList = NULL; + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_UE_CapabilityRAT_ContainerList, + (void **)&ue_CapabilityRAT_ContainerList, + (uint8_t *)req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, + (int) req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + AssertFatal(1==0,"UE Capability RAT ContainerList decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_UE_CapabilityRAT_ContainerList, ue_CapabilityRAT_ContainerList, 1 ); + return; + } + //To fill ue_context.UE_Capability_MRDC, ue_context.UE_Capability_nr ... + int NR_index = -1; + for(int i = 0;i < ue_CapabilityRAT_ContainerList->list.count; i++){ + if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_nr){ + LOG_I(NR_RRC, "DU received NR_RAT_Type_nr UE capabilities Info through the UE Context Setup Request from the CU \n"); + if(ue_context_p->ue_context.UE_Capability_nr){ + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + ue_context_p->ue_context.UE_Capability_nr = 0; + } + + dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_NR_Capability, + (void**)&ue_context_p->ue_context.UE_Capability_nr, + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, + 0,0); + if(LOG_DEBUGFLAG(DEBUG_ASN1)){ + xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + } + + if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ + LOG_E(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt),dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability,ue_context_p->ue_context.UE_Capability_nr); + ue_context_p->ue_context.UE_Capability_nr = 0; + } + + ue_context_p->ue_context.UE_Capability_size = + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; + if(NR_index != -1){ + LOG_E(NR_RRC,"fatal: more than 1 eutra capability\n"); + exit(1); + } + NR_index = i; + } + + if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_eutra_nr){ + LOG_I(NR_RRC, "DU received NR_RAT_Type_eutra_nr UE capabilities Info through the UE Context Setup Request from the CU \n"); + if(ue_context_p->ue_context.UE_Capability_MRDC){ + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + ue_context_p->ue_context.UE_Capability_MRDC = 0; + } + dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_MRDC_Capability, + (void**)&ue_context_p->ue_context.UE_Capability_MRDC, + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.buf, + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size, + 0,0); + if(LOG_DEBUGFLAG(DEBUG_ASN1)){ + xer_fprint(stdout,&asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + } + + if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)){ + LOG_E(NR_RRC,PROTOCOL_NR_RRC_CTXT_FMT" Failed to decode nr UE capabilities (%zu bytes)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt),dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability,ue_context_p->ue_context.UE_Capability_MRDC); + ue_context_p->ue_context.UE_Capability_MRDC = 0; + } + ue_context_p->ue_context.UE_MRDC_Capability_size = + ue_CapabilityRAT_ContainerList->list.array[i]->ue_CapabilityRAT_Container.size; + } + + if(ue_CapabilityRAT_ContainerList->list.array[i]->rat_Type == + NR_RAT_Type_eutra){ + //TODO + } + } + } + } + uint8_t drb_id_to_setup_start = 0; uint8_t nb_drb_to_setup = 0; long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) @@ -3320,22 +3258,38 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8; extern instance_t DUuniqInstance; if (!drb_id_to_setup_start) drb_id_to_setup_start = drb_p.drb_id; - incoming_teid=newGtpuCreateTunnel(DUuniqInstance, - req->rnti, - drb_p.drb_id, - drb_p.drb_id, - drb_p.up_ul_tnl[0].teid, - addr, - drb_p.up_ul_tnl[0].port, - DURecvCb); + incoming_teid = newGtpuCreateTunnel(DUuniqInstance, + req->rnti, + drb_p.drb_id, + drb_p.drb_id, + drb_p.up_ul_tnl[0].teid, + -1, // no qfi + addr, + drb_p.up_ul_tnl[0].port, + DURecvCb, + NULL); } } - NR_CellGroupConfig_t *cellGroupConfig; - cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - fill_mastercellGroupConfig(cellGroupConfig, ue_context_p->ue_context.masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); + NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); + if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length>0) + // FIXME: fill_mastercellGroupConfig() won't fill the right priorities or + // bearer IDs for the DRBs + fill_mastercellGroupConfig(cellGroupConfig, ue_context_p->ue_context.masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority); apply_macrlc_config(rrc, ue_context_p, &ctxt); + + if(req->rrc_container_length > 0){ + mem_block_t *pdcp_pdu_p = get_free_mem_block(req->rrc_container_length, __func__); + memcpy(&pdcp_pdu_p->data[0], req->rrc_container, req->rrc_container_length); + du_rlc_data_req(&ctxt, 1, 0x00, 1, 1, 0, req->rrc_container_length, pdcp_pdu_p); + LOG_I(F1AP, "Printing RRC Container of UE context setup request: \n"); + for (int j=0; j<req->rrc_container_length; j++){ + printf("%02x ", pdcp_pdu_p->data[j]); + } + printf("\n"); + } + /* Fill the UE context setup response ITTI message to send to F1AP */ resp->gNB_CU_ue_id = req->gNB_CU_ue_id; resp->rnti = ctxt.rnti; @@ -3370,25 +3324,188 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha else{ LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context setup request at the DU\n"); } - resp->du_to_cu_rrc_information = calloc(1,1024*sizeof(uint8_t)); + /* fixme: + * Here we should be encoding the updates on cellgroupconfig based on the content of UE capabilities + */ + resp->du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t)); + resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024); asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, NULL, - (void *)cellGroupConfig, - resp->du_to_cu_rrc_information, + ue_context_p->ue_context.masterCellGroup, //(void *)cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig, 1024); - resp->du_to_cu_rrc_information_length = (enc_rval.encoded+7)>>3; + if (enc_rval.encoded == -1) { + LOG_E(F1AP,"Could not encode ue_context.masterCellGroup, failed element %s\n",enc_rval.failed_type->name); + exit(-1); + } + resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3; free(cellGroupConfig); itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p); } +static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, const char *msg_name, instance_t instance){ + + f1ap_ue_context_setup_t * req=&F1AP_UE_CONTEXT_MODIFICATION_REQ(msg_p); + protocol_ctxt_t ctxt = { + .rnti = req->rnti, + .module_id = instance, + .instance = instance, + .enb_flag = 1, + .eNB_index = instance + }; + gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; + gNB_MAC_INST *mac = RC.nrmac[ctxt.module_id]; + struct rrc_gNB_ue_context_s *ue_context_p = + rrc_gNB_get_ue_context(rrc, ctxt.rnti); + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_RESP); + f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_MODIFICATION_RESP(message_p); + uint32_t incoming_teid = 0; + NR_CellGroupConfig_t *cellGroupConfig = NULL; + + /* Configure SRB2 */ + NR_SRB_ToAddMod_t *SRB2_config = NULL; + NR_SRB_ToAddModList_t *SRB_configList = NULL; + uint8_t SRBs_before_new_addition = 0; + + if(req->srbs_to_be_setup_length>0){ + if(ue_context_p->ue_context.SRB_configList == NULL){ + LOG_W(NR_RRC, "The SRB list of the UE context is empty before the addition of new SRB at the DU \n"); + ue_context_p->ue_context.SRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.SRB_configList)); + } + SRB_configList = ue_context_p->ue_context.SRB_configList; + SRBs_before_new_addition = SRB_configList->list.count; + for (int i=0; i<req->srbs_to_be_setup_length; i++){ + SRB2_config = CALLOC(1, sizeof(*SRB2_config)); + SRB2_config->srb_Identity = req->srbs_to_be_setup[i].srb_id; + ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); + } + } + + /* Configure DRB */ + NR_DRB_ToAddMod_t *DRB_config = NULL; + NR_DRB_ToAddModList_t *DRB_configList = NULL; + if(req->drbs_to_be_setup_length>0){ + if(ue_context_p->ue_context.DRB_configList == NULL){ + ue_context_p->ue_context.DRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.DRB_configList)); + } + DRB_configList = ue_context_p->ue_context.DRB_configList; + for (int i=0; i<req->drbs_to_be_setup_length; i++){ + DRB_config = CALLOC(1, sizeof(*DRB_config)); + DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id; + ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config); + f1ap_drb_to_be_setup_t drb_p = req->drbs_to_be_setup[i]; + transport_layer_addr_t addr; + memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address)); + addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8; + extern instance_t DUuniqInstance; + incoming_teid = newGtpuCreateTunnel(DUuniqInstance, + req->rnti, + drb_p.drb_id, + drb_p.drb_id, + drb_p.up_ul_tnl[0].teid, + -1, // no qfi + addr, + drb_p.up_ul_tnl[0].port, + DURecvCb, + NULL); + } + } + + if(req->srbs_to_be_setup_length>0 || req->drbs_to_be_setup_length>0){ + cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); + uint8_t drb_id_to_setup_start = 1; + long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future) + fill_mastercellGroupConfig(cellGroupConfig, + ue_context_p->ue_context.masterCellGroup, + rrc->um_on_default_drb, + drb_id_to_setup_start < 2 ? 1 : 0, + drb_id_to_setup_start, + req->drbs_to_be_setup_length, + drb_priority); + apply_macrlc_config(rrc, ue_context_p, &ctxt); + } + if(req->ReconfigComplOutcome == RRCreconf_failure){ + LOG_W(NR_RRC, "CU reporting RRC Reconfiguration failure \n"); + } + else if(req->ReconfigComplOutcome == RRCreconf_success){ + LOG_I(NR_RRC, "CU reporting RRC Reconfiguration success \n"); + if(ue_context_p->ue_context.DRB_configList!=NULL){ + LOG_I(NR_RRC, "Send first DDD buffer status reporting towards the CU through an ITTI message to gtp-u \n"); + uint8_t drb_id = ue_context_p->ue_context.DRB_configList->list.array[0]->drb_Identity; + rnti_t rnti = ue_context_p->ue_context.rnti; + int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(rnti, drb_id); + LOG_I(NR_RRC, "Reported in DDD drb_id:%d, rnti:%d\n", drb_id, rnti); + MessageDef *msg = itti_alloc_new_message_sized(TASK_RRC_GNB, 0, GTPV1U_DU_BUFFER_REPORT_REQ, + sizeof(gtpv1u_gnb_tunnel_data_req_t)); + gtpv1u_DU_buffer_report_req_t *req=>PV1U_DU_BUFFER_REPORT_REQ(msg); + req->pdusession_id = drb_id; + req->rnti = rnti; + req->buffer_availability = rlc_tx_buffer_space; //10000000; //Hardcoding to be removed and read the actual RLC buffer availability instead + extern instance_t DUuniqInstance; + itti_send_msg_to_task(TASK_GTPV1_U, DUuniqInstance, msg); + + } + } + + /* Fill the UE context setup response ITTI message to send to F1AP */ + resp->gNB_CU_ue_id = req->gNB_CU_ue_id; + resp->rnti = ctxt.rnti; + if(DRB_configList){ + if(DRB_configList->list.count > 0){ + resp->drbs_to_be_setup = calloc(1,DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t)); + resp->drbs_to_be_setup_length = DRB_configList->list.count; + for (int i=0; i<DRB_configList->list.count; i++){ + resp->drbs_to_be_setup[i].drb_id = DRB_configList->list.array[i]->drb_Identity; + resp->drbs_to_be_setup[i].rlc_mode = RLC_MODE_AM; + resp->drbs_to_be_setup[i].up_dl_tnl[0].teid = incoming_teid; + resp->drbs_to_be_setup[i].up_dl_tnl[0].tl_address = inet_addr(mac->eth_params_n.my_addr); + resp->drbs_to_be_setup[i].up_dl_tnl_length = 1; + } + } + else{ + LOG_W(NR_RRC, "No DRB added upon reception of F1 UE context modification request with a DRB to setup list\n"); + } + } + if(SRB_configList){ + if(SRB_configList->list.count >0 && SRBs_before_new_addition < SRB_configList->list.count){ + resp->srbs_to_be_setup = calloc(1,req->srbs_to_be_setup_length*sizeof(f1ap_srb_to_be_setup_t)); + resp->srbs_to_be_setup_length = req->srbs_to_be_setup_length; + for (int i=SRBs_before_new_addition; i<SRB_configList->list.count; i++){ + resp->srbs_to_be_setup[i-SRBs_before_new_addition].srb_id = SRB_configList->list.array[i]->srb_Identity; + } + } + else{ + LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n"); + } + } + else{ + LOG_W(NR_RRC, "No SRB added upon reception of F1 UE Context modification request at the DU\n"); + } + + //if(cellGroupConfig != NULL) { + resp->du_to_cu_rrc_information = calloc(1,sizeof(du_to_cu_rrc_information_t)); + resp->du_to_cu_rrc_information->cellGroupConfig = calloc(1,1024); + asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_CellGroupConfig, + NULL, + ue_context_p->ue_context.masterCellGroup, //(void *)cellGroupConfig, + resp->du_to_cu_rrc_information->cellGroupConfig, + 1024); + resp->du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded+7)>>3; + //} + itti_send_msg_to_task (TASK_DU_F1, ctxt.module_id, message_p); +} + static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const char *msg_name, instance_t instance){ f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); - protocol_ctxt_t ctxt; - ctxt.rnti = resp->rnti; - ctxt.module_id = instance; - ctxt.instance = instance; - ctxt.enb_flag = 1; + protocol_ctxt_t ctxt = { + .rnti = resp->rnti, + .module_id = instance, + .instance = instance, + .enb_flag = 1, + .eNB_index = instance + }; gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rnti); NR_CellGroupConfig_t *cellGroupConfig = NULL; @@ -3396,8 +3513,8 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch asn_dec_rval_t dec_rval = uper_decode_complete( NULL, &asn_DEF_NR_CellGroupConfig, (void **)&cellGroupConfig, - (uint8_t *)resp->du_to_cu_rrc_information, - (int) resp->du_to_cu_rrc_information_length); + (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig, + (int) resp->du_to_cu_rrc_information->cellGroupConfig_length); if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { AssertFatal(1==0,"Cell group config decode error\n"); @@ -3412,20 +3529,90 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch } if(cellGroupConfig->rlc_BearerToAddModList!=NULL){ if(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList != NULL){ - LOG_I(NR_RRC, "rlc_BearerToAddModList not empty before filling it \n"); - free(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList); + int ue_ctxt_rlc_Bearers = ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list.count; + for(int i=ue_ctxt_rlc_Bearers; i<ue_ctxt_rlc_Bearers + cellGroupConfig->rlc_BearerToAddModList->list.count; i++){ + ASN_SEQUENCE_ADD(&ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list, + cellGroupConfig->rlc_BearerToAddModList->list.array[i-ue_ctxt_rlc_Bearers]); + } } - ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); - memcpy(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, + else{ + LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n"); + ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + memcpy(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + } } xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, ue_context_p->ue_context.masterCellGroup); + if (ue_context_p->ue_context.established_pdu_sessions_flag == 1) { + rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig); + } else { + rrc_gNB_generate_defaultRRCReconfiguration(&ctxt, ue_context_p); + } + free(cellGroupConfig->rlc_BearerToAddModList); free(cellGroupConfig); } +static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, const char *msg_name, instance_t instance){ + + f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p); + protocol_ctxt_t ctxt = { + .rnti = resp->rnti, + .module_id = instance, + .instance = instance, + .enb_flag = 1, + .eNB_index = instance + }; + gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id]; + struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rnti); + NR_CellGroupConfig_t *cellGroupConfig = NULL; + + if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){ + asn_dec_rval_t dec_rval = uper_decode_complete( NULL, + &asn_DEF_NR_CellGroupConfig, + (void **)&cellGroupConfig, + (uint8_t *)resp->du_to_cu_rrc_information->cellGroupConfig, + (int) resp->du_to_cu_rrc_information->cellGroupConfig_length); + + if((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + AssertFatal(1==0,"Cell group config decode error\n"); + // free the memory + SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, cellGroupConfig, 1 ); + return; + } + //xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, cellGroupConfig); + + if(ue_context_p->ue_context.masterCellGroup == NULL){ + ue_context_p->ue_context.masterCellGroup = calloc(1, sizeof(NR_CellGroupConfig_t)); + } + + if(cellGroupConfig->rlc_BearerToAddModList!=NULL){ + if(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList != NULL){ + int ue_ctxt_rlc_Bearers = ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list.count; + for(int i=ue_ctxt_rlc_Bearers; i<ue_ctxt_rlc_Bearers + cellGroupConfig->rlc_BearerToAddModList->list.count; i++){ + ASN_SEQUENCE_ADD(&ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList->list, + cellGroupConfig->rlc_BearerToAddModList->list.array[i-ue_ctxt_rlc_Bearers]); + } + } + else{ + LOG_W(NR_RRC, "Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response \n"); + ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + memcpy(ue_context_p->ue_context.masterCellGroup->rlc_BearerToAddModList, cellGroupConfig->rlc_BearerToAddModList, + sizeof(*cellGroupConfig->rlc_BearerToAddModList)); + } + } + LOG_I(NR_RRC, "Updated master cell group configuration stored at the UE context of the CU:\n"); + xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, ue_context_p->ue_context.masterCellGroup); + + rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, cellGroupConfig); + + free(cellGroupConfig->rlc_BearerToAddModList); + free(cellGroupConfig); + } +} + unsigned int mask_flip(unsigned int x) { return((((x>>8) + (x<<8))&0xffff)>>6); } @@ -3590,7 +3777,7 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { gNB_MAC_INST *nrmac=RC.nrmac[ctxt_pP->module_id]; //WHAT A BEAUTIFULL RACE CONDITION !!! if (fd) { - if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == TRUE) { + if (ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.presence == true) { fprintf(fd,"NR RRC UE rnti %x: S-TMSI %x failure timer %d/8\n", ue_context_p->ue_id_rnti, ue_context_p->ue_context.Initialue_identity_5g_s_TMSI.fiveg_tmsi, @@ -3627,15 +3814,27 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) { // Remove here the MAC and RRC context when RRC is not connected or gNB is not connected to CN5G if(ue_context_p->ue_context.StatusRrc < NR_RRC_CONNECTED || ue_context_p->ue_context.gNB_ue_ngap_id == 0) { - mac_remove_nr_ue(nrmac, ctxt_pP->rnti); - rrc_rlc_remove_ue(ctxt_pP); - pdcp_remove_UE(ctxt_pP); - - /* remove RRC UE Context */ - ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti); - if (ue_context_p) { - rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p); - LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti); + if(!NODE_IS_CU(RC.nrrrc[ctxt_pP->instance]->node_type)){ + mac_remove_nr_ue(nrmac, ctxt_pP->rnti); + rrc_rlc_remove_ue(ctxt_pP); + pdcp_remove_UE(ctxt_pP); + + /* remove RRC UE Context */ + ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[ctxt_pP->module_id], ctxt_pP->rnti); + if (ue_context_p) { + rrc_gNB_remove_ue_context(ctxt_pP, RC.nrrrc[ctxt_pP->module_id], ue_context_p); + LOG_I(NR_RRC, "remove UE %x \n", ctxt_pP->rnti); + } + } + // In case of CU trigger UE context release command towards the DU + else{ + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_RELEASE_CMD); + f1ap_ue_context_release_cmd_t *rel_cmd=&F1AP_UE_CONTEXT_RELEASE_CMD (message_p); + rel_cmd->rnti = ctxt_pP->rnti; + rel_cmd->cause = F1AP_CAUSE_RADIO_NETWORK; + rel_cmd->cause_value = 10; // 10 = F1AP_CauseRadioNetwork_normal_release + itti_send_msg_to_task(TASK_CU_F1, ctxt_pP->module_id, message_p); } } @@ -3722,73 +3921,31 @@ void *rrc_gnb_task(void *args_p) { nr_rrc_subframe_process(&RRC_SUBFRAME_PROCESS(msg_p).ctxt, RRC_SUBFRAME_PROCESS(msg_p).CC_id); break; - /* Messages from MAC */ - case NR_RRC_MAC_CCCH_DATA_IND: - { - instance_t i; - for (i=0; i<RC.nb_nr_inst; i++) { - // first get RRC instance (note, no the ITTI instance) - gNB_RRC_INST *rrc = RC.nrrrc[i]; - - if (rrc->nr_cellid == NR_RRC_MAC_CCCH_DATA_IND(msg_p).nr_cellid) - break; - } - AssertFatal(i!=RC.nb_nr_inst, "Cell_id not found\n"); - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, - i, - GNB_FLAG_YES, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).rnti, - msg_p->ittiMsgHeader.lte_time.frame, - msg_p->ittiMsgHeader.lte_time.slot); - LOG_I(NR_RRC,"Decoding CCCH : ue %d, inst %ld, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n", - ctxt.rnti, - i, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id, - &ctxt, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size); - - if (NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= CCCH_SDU_SIZE) { - LOG_I(NR_RRC, "CCCH message has size %d > %d\n", - NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,CCCH_SDU_SIZE); - break; - } - - nr_rrc_gNB_decode_ccch(&ctxt, - (uint8_t *)NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container, - NR_RRC_MAC_CCCH_DATA_IND(msg_p).CC_id); - - if (NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container) { - free(NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container->buf); - free(NR_RRC_MAC_CCCH_DATA_IND(msg_p).du_to_cu_rrc_container); - } - } - break; + case F1AP_INITIAL_UL_RRC_MESSAGE: + AssertFatal(NODE_IS_CU(RC.nrrrc[instance]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[instance]->node_type), + "should not receive F1AP_INITIAL_UL_RRC_MESSAGE, need call by CU!\n"); + rrc_gNB_process_initial_ul_rrc_message(&F1AP_INITIAL_UL_RRC_MESSAGE(msg_p)); + break; /* Messages from PDCP */ - case NR_RRC_DCCH_DATA_IND: + case F1AP_UL_RRC_MESSAGE: PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, - NR_RRC_DCCH_DATA_IND(msg_p).rnti, - msg_p->ittiMsgHeader.lte_time.frame, - msg_p->ittiMsgHeader.lte_time.slot); - LOG_D(NR_RRC,"Decoding DCCH : ue %d, inst %ld, ctxt %p, size %d\n", + F1AP_UL_RRC_MESSAGE(msg_p).rnti, + 0, + 0); + LOG_D(NR_RRC,"Decoding DCCH %d: ue %04x, inst %ld, ctxt %p, size %d\n", + F1AP_UL_RRC_MESSAGE(msg_p).srb_id, ctxt.rnti, instance, &ctxt, - NR_RRC_DCCH_DATA_IND(msg_p).sdu_size); - LOG_D(NR_RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Received on DCCH %d %s\n", - PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt), - NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, - msg_name_p); + F1AP_UL_RRC_MESSAGE(msg_p).rrc_container_length); rrc_gNB_decode_dcch(&ctxt, - NR_RRC_DCCH_DATA_IND(msg_p).dcch_index, - NR_RRC_DCCH_DATA_IND(msg_p).sdu_p, - NR_RRC_DCCH_DATA_IND(msg_p).sdu_size); - result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), NR_RRC_DCCH_DATA_IND(msg_p).sdu_p); - + F1AP_UL_RRC_MESSAGE(msg_p).srb_id, + F1AP_UL_RRC_MESSAGE(msg_p).rrc_container, + F1AP_UL_RRC_MESSAGE(msg_p).rrc_container_length); + free(F1AP_UL_RRC_MESSAGE(msg_p).rrc_container); break; case NGAP_DOWNLINK_NAS: @@ -3821,17 +3978,30 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_f1_setup_req(&F1AP_SETUP_REQ(msg_p)); break; - case NR_DU_RRC_DL_INDICATION: - rrc_process_DU_DL(msg_p, msg_name_p, instance); - break; + case NR_DU_RRC_DL_INDICATION: + rrc_process_DU_DL(msg_p, msg_name_p, instance); + break; - case F1AP_UE_CONTEXT_SETUP_REQ: - rrc_DU_process_ue_context_setup_request(msg_p, msg_name_p, instance); - break; + case F1AP_UE_CONTEXT_SETUP_REQ: + rrc_DU_process_ue_context_setup_request(msg_p, msg_name_p, instance); + break; - case F1AP_UE_CONTEXT_SETUP_RESP: - rrc_CU_process_ue_context_setup_response(msg_p, msg_name_p, instance); - break; + case F1AP_UE_CONTEXT_SETUP_RESP: + rrc_CU_process_ue_context_setup_response(msg_p, msg_name_p, instance); + break; + + case F1AP_UE_CONTEXT_MODIFICATION_RESP: + rrc_CU_process_ue_context_modification_response(msg_p, msg_name_p, instance); + break; + + case F1AP_UE_CONTEXT_MODIFICATION_REQ: + rrc_DU_process_ue_context_modification_request(msg_p, msg_name_p, instance); + break; + + case F1AP_UE_CONTEXT_RELEASE_CMD: + LOG_W(NR_RRC, "Received F1AP_UE_CONTEXT_RELEASE_CMD for processing at the RRC layer of the DU. Processing function " + "implementation is pending\n"); + break; /* Messages from X2AP */ case X2AP_ENDC_SGNB_ADDITION_REQ: @@ -3929,17 +4099,6 @@ rrc_gNB_generate_SecurityModeCommand( size, rrc_gNB_mui, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM,size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else LOG_D(NR_RRC,"calling rrc_data_req :securityModeCommand\n"); nr_rrc_data_req(ctxt_pP, DCCH, @@ -3948,7 +4107,6 @@ rrc_gNB_generate_SecurityModeCommand( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif break; default : @@ -4001,17 +4159,6 @@ rrc_gNB_generate_UECapabilityEnquiry( size, rrc_gNB_mui, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else nr_rrc_data_req(ctxt_pP, DCCH, rrc_gNB_mui++, @@ -4019,7 +4166,6 @@ rrc_gNB_generate_UECapabilityEnquiry( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif break; default : @@ -4061,17 +4207,6 @@ rrc_gNB_generate_RRCRelease( rrc_gNB_mui, DCCH); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_UE_SIM, ctxt_pP->instance, message_p); -#else if (NODE_IS_CU(RC.nrrrc[ctxt_pP->module_id]->node_type)) { uint8_t *message_buffer = itti_malloc (TASK_RRC_GNB, TASK_CU_F1, size); memcpy (message_buffer, buffer, size); @@ -4094,7 +4229,6 @@ rrc_gNB_generate_RRCRelease( rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE(ctxt_pP->instance, ue_context_pP->ue_context.gNB_ue_ngap_id); ue_context_pP->ue_context.ue_release_timer_rrc = 1; } -#endif } void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) { @@ -4102,5 +4236,6 @@ void nr_rrc_trigger(protocol_ctxt_t *ctxt, int CC_id, int frame, int subframe) message_p = itti_alloc_new_message(TASK_RRC_GNB, 0, RRC_SUBFRAME_PROCESS); RRC_SUBFRAME_PROCESS(message_p).ctxt = *ctxt; RRC_SUBFRAME_PROCESS(message_p).CC_id = CC_id; + LOG_D(NR_RRC, "Time in RRC: %u/ %u \n", frame, subframe); itti_send_msg_to_task(TASK_RRC_GNB, ctxt->module_id, message_p); } diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 96ec63443357cd81563d8664595030ac188f03d5..8f391417e0d991d518dd811e123981491def28dd 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -307,7 +307,6 @@ nr_rrc_pdcp_config_security( //uint8_t *k_kdf = NULL; static int print_keys= 1; - /* Derive the keys from kgnb */ if (SRB_configList != NULL) { nr_derive_key_up_enc(ue_context_pP->ue_context.ciphering_algorithm, @@ -475,7 +474,6 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( rrc_gNB_ue_context_t *ue_context_p = NULL; protocol_ctxt_t ctxt={0}; uint8_t pdu_sessions_done = 0; - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp; uint8_t inde_list[NR_NB_RB_MAX - 3]= {0}; int ret = 0; @@ -504,7 +502,7 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions; if (nb_pdusessions_tosetup != 0) { - memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0}; for (int i = 0; i < NR_NB_RB_MAX - 3; i++) { if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE) continue; @@ -513,6 +511,8 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].pdusession_id; create_tunnel_req.incoming_rb_id[pdu_sessions_done] = i+1; create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].gtp_teid; + // To be developped: hardcoded first flow + create_tunnel_req.outgoing_qfi[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].qos[0].qfi; create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.length; memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer, NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.buffer, @@ -709,7 +709,7 @@ rrc_gNB_process_security( rrc_gNB_ue_context_t *const ue_context_pP, ngap_security_capabilities_t *security_capabilities_pP ) { - boolean_t changed = FALSE; + bool changed = false; NR_CipheringAlgorithm_t cipheringAlgorithm; e_NR_IntegrityProtAlgorithm integrityProtAlgorithm; /* Save security parameters */ @@ -727,14 +727,14 @@ rrc_gNB_process_security( if (ue_context_pP->ue_context.ciphering_algorithm != cipheringAlgorithm) { ue_context_pP->ue_context.ciphering_algorithm = cipheringAlgorithm; - changed = TRUE; + changed = true; } integrityProtAlgorithm = rrc_gNB_select_integrity(ctxt_pP, ue_context_pP->ue_context.security_capabilities.nRintegrity_algorithms); if (ue_context_pP->ue_context.integrity_algorithm != integrityProtAlgorithm) { ue_context_pP->ue_context.integrity_algorithm = integrityProtAlgorithm; - changed = TRUE; + changed = true; } LOG_I (NR_RRC, "[gNB %d][UE %x] Selected security algorithms (%p): %lx, %x, %s\n", @@ -824,17 +824,6 @@ rrc_gNB_process_NGAP_DOWNLINK_NAS( case ngran_gNB: { // rrc_mac_config_req_gNB -#ifdef ITTI_SIM - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_GNB, TASK_RRC_UE_SIM, length); - memcpy (message_buffer, buffer, length); - MessageDef *message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, GNB_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = length; - itti_send_msg_to_task (TASK_RRC_UE_SIM, instance, message_p); - LOG_I(NR_RRC, "Send DL NAS message \n"); -#else /* Transfer data to PDCP */ nr_rrc_data_req ( &ctxt, @@ -844,7 +833,6 @@ rrc_gNB_process_NGAP_DOWNLINK_NAS( length, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif } break; @@ -1004,6 +992,7 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id; create_tunnel_req.incoming_rb_id[pdu_sessions_done]= i+1; create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid; + create_tunnel_req.outgoing_qfi[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].qos[0].qfi; memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer, NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer, sizeof(uint8_t)*20); @@ -1050,7 +1039,46 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( // TEST // ue_context_p->ue_context.pdusession[0].status = PDU_SESSION_STATUS_DONE; // rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(&ctxt, ue_context_p, 0); - rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p); + if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)){ + rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL); + } + else{ + /*Generate a UE context modification request message towards the DU to instruct the DU + *for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/ + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); + f1ap_ue_context_setup_t *req=&F1AP_UE_CONTEXT_MODIFICATION_REQ (message_p); + req->rnti = ue_context_p->ue_context.rnti; + req->mcc = RC.nrrrc[ctxt.module_id]->configuration.mcc[0]; + req->mnc = RC.nrrrc[ctxt.module_id]->configuration.mnc[0]; + req->mnc_digit_length = RC.nrrrc[ctxt.module_id]->configuration.mnc_digit_length[0]; + req->nr_cellid = RC.nrrrc[ctxt.module_id]->nr_cellid; + + /*Instruction towards the DU for SRB2 configuration*/ + req->srbs_to_be_setup = malloc(1*sizeof(f1ap_srb_to_be_setup_t)); + req->srbs_to_be_setup_length = 1; + f1ap_srb_to_be_setup_t *SRBs=req->srbs_to_be_setup; + SRBs[0].srb_id = 2; + SRBs[0].lcid = 2; + + /*Instruction towards the DU for DRB configuration and tunnel creation*/ + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; + memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); + req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)); + req->drbs_to_be_setup_length = 1; + f1ap_drb_to_be_setup_t *DRBs=req->drbs_to_be_setup; + LOG_D(RRC, "Length of DRB list:%d \n", req->drbs_to_be_setup_length); + DRBs[0].drb_id = 1; + DRBs[0].rlc_mode = RLC_MODE_AM; + DRBs[0].up_ul_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr); + DRBs[0].up_ul_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd; + DRBs[0].up_ul_tnl_length = 1; + DRBs[0].up_dl_tnl[0].tl_address = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr); + DRBs[0].up_dl_tnl[0].port=RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd; + DRBs[0].up_dl_tnl_length = 1; + + itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p); + } return(0); } } @@ -1088,17 +1116,17 @@ rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ( ue_context_p->ue_context.gNB_ue_ngap_id = gNB_ue_ngap_id; { int j; - boolean_t is_treated[NGAP_MAX_PDUSESSION] = {FALSE}; + bool is_treated[NGAP_MAX_PDUSESSION] = {false}; uint8_t nb_of_failed_pdusessions = 0; for (i = 0; i < nb_pdusessions_tomodify; i++) { - if (is_treated[i] == TRUE) { + if (is_treated[i] == true) { continue; } //Check if same PDU session ID to handle multiple pdu sessions for (j = i+1; j < nb_pdusessions_tomodify; j++) { - if (is_treated[j] == FALSE && + if (is_treated[j] == false && NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[j].pdusession_id == NGAP_PDUSESSION_MODIFY_REQ(msg_p).pdusession_modify_params[i].pdusession_id) { // handle multiple pdu session id @@ -1109,12 +1137,12 @@ rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ( ue_context_p->ue_context.modify_pdusession[j].cause = NGAP_CAUSE_RADIO_NETWORK; ue_context_p->ue_context.modify_pdusession[j].cause_value = NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances; nb_of_failed_pdusessions++; - is_treated[i] = TRUE; - is_treated[j] = TRUE; + is_treated[i] = true; + is_treated[j] = true; } } // handle multiple pdu session id case - if (is_treated[i] == TRUE) { + if (is_treated[i] == true) { LOG_D(NR_RRC, "handle multiple pdu session id \n"); ue_context_p->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_NEW; ue_context_p->ue_context.modify_pdusession[i].param.pdusession_id = @@ -1157,13 +1185,13 @@ rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ( ue_context_p->ue_context.modify_pdusession[i].param.gtp_teid = ue_context_p->ue_context.pduSession[j].param.gtp_teid; - is_treated[i] = TRUE; + is_treated[i] = true; break; } } // handle Unknown pdu session ID - if (is_treated[i] == FALSE) { + if (is_treated[i] == false) { LOG_D(NR_RRC, "handle Unknown pdu session ID \n"); ue_context_p->ue_context.modify_pdusession[i].status = PDU_SESSION_STATUS_NEW; ue_context_p->ue_context.modify_pdusession[i].param.pdusession_id = @@ -1171,7 +1199,7 @@ rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ( ue_context_p->ue_context.modify_pdusession[i].cause = NGAP_CAUSE_RADIO_NETWORK; ue_context_p->ue_context.modify_pdusession[i].cause_value = NGAP_CauseRadioNetwork_unknown_PDU_session_ID; nb_of_failed_pdusessions++; - is_treated[i] = TRUE; + is_treated[i] = true; } } diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index b8ff19b749e93e95428d72954b03d1ab58d93f87..540ac5d075a6ea58b22221228e5e887f64170e86 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -37,61 +37,6 @@ #include "rrc_gNB_UE_context.h" -//------------------------------------------------------------------------------ -void nr_uid_linear_allocator_init( - nr_uid_allocator_t *const uid_pP -) -//------------------------------------------------------------------------------ -{ - memset(uid_pP, 0, sizeof(nr_uid_allocator_t)); -} - -//------------------------------------------------------------------------------ -uid_nr_t nr_uid_linear_allocator_new(gNB_RRC_INST *const rrc_instance_pP) -//------------------------------------------------------------------------------ -{ - unsigned int i; - unsigned int bit_index = 1; - uid_nr_t uid = 0; - nr_uid_allocator_t *uia_p = &rrc_instance_pP->uid_allocator; - - for (i=0; i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE; i++) { - if (uia_p->bitmap[i] != UINT_MAX) { - bit_index = 1; - uid = 0; - - while ((uia_p->bitmap[i] & bit_index) == bit_index) { - bit_index = bit_index << 1; - uid += 1; - } - - uia_p->bitmap[i] |= bit_index; - return uid + (i*sizeof(unsigned int)*8); - } - } - - return UINT_MAX; -} - - -//------------------------------------------------------------------------------ -void -nr_uid_linear_allocator_free( - gNB_RRC_INST *rrc_instance_pP, - uid_nr_t uidP -) -//------------------------------------------------------------------------------ -{ - unsigned int i = uidP/sizeof(unsigned int)/8; - unsigned int bit = uidP % (sizeof(unsigned int) * 8); - unsigned int value = ~(0x00000001 << bit); - - if (i < UID_LINEAR_ALLOCATOR_BITMAP_SIZE) { - rrc_instance_pP->uid_allocator.bitmap[i] &= value; - } -} - - //------------------------------------------------------------------------------ int rrc_gNB_compare_ue_rnti_id( struct rrc_gNB_ue_context_s *c1_pP, struct rrc_gNB_ue_context_s *c2_pP) @@ -130,7 +75,7 @@ rrc_gNB_allocate_new_UE_context( } memset(new_p, 0, sizeof(struct rrc_gNB_ue_context_s)); - new_p->local_uid = nr_uid_linear_allocator_new(rrc_instance_pP); + new_p->local_uid = uid_linear_allocator_new(&rrc_instance_pP->uid_allocator); for(int i = 0; i < NB_RB_MAX; i++) { new_p->ue_context.e_rab[i].xid = -1; @@ -177,12 +122,12 @@ void rrc_gNB_free_mem_UE_context( { LOG_T(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + PROTOCOL_NR_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP), ue_context_pP); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]); + //ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]); + //ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]); // empty the internal fields of the UE context here } @@ -195,25 +140,25 @@ void rrc_gNB_remove_ue_context( //------------------------------------------------------------------------------ { if (rrc_instance_pP == NULL) { - LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Bad RRC instance\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_E(RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Bad RRC instance\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); return; } if (ue_context_pP == NULL) { - LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Trying to free a NULL UE context\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + LOG_E(RRC, PROTOCOL_NR_RRC_CTXT_UE_FMT" Trying to free a NULL UE context\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); return; } RB_REMOVE(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_pP); rrc_gNB_free_mem_UE_context(ctxt_pP, ue_context_pP); - nr_uid_linear_allocator_free(rrc_instance_pP, ue_context_pP->local_uid); + uid_linear_allocator_free(&rrc_instance_pP->uid_allocator, ue_context_pP->local_uid); free(ue_context_pP); rrc_instance_pP->Nb_ue --; LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Removed UE context\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + PROTOCOL_NR_RRC_CTXT_UE_FMT" Removed UE context\n", + PROTOCOL_NR_RRC_CTXT_UE_ARGS(ctxt_pP)); } //----------------------------------------------------------------------------- diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index 73bd93e737c9ed6df9262820beb2e5ae7105c27f..4009f2617f062933319e289903852cff4be3d46a 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -34,27 +34,6 @@ #include "COMMON/platform_types.h" #include "nr_rrc_defs.h" - -void -nr_uid_linear_allocator_init( - nr_uid_allocator_t* const uid_pP -); - -uid_t -nr_uid_linear_allocator_new( - gNB_RRC_INST* rrc_instance_pP -); - - -void -nr_uid_linear_allocator_free( - gNB_RRC_INST* rrc_instance_pP, - uid_t uidP -); - - - - int rrc_gNB_compare_ue_rnti_id( struct rrc_gNB_ue_context_s* c1_pP, struct rrc_gNB_ue_context_s* c2_pP diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 07a6bd85be15c05e7b980dbf875a985816288506..b3eada8136ad9b1c11b918c689777bca26b28dbc 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -349,7 +349,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ // configure MAC and RLC if (NODE_IS_DU(rrc->node_type)) { rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, @@ -362,7 +361,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ue_context_p->ue_context.secondaryCellGroup); } else { rrc_mac_config_req_gNB(rrc->module_id, - rrc->configuration.ssb_SubcarrierOffset, rrc->configuration.pdsch_AntennaPorts, rrc->configuration.pusch_AntennaPorts, rrc->configuration.sib1_tda, diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index a6fef46c34b732159377a00d7cf471ccf1a0181c..08baeb3d454256af90d271c09e5b1e72fe4e282f 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -47,9 +47,6 @@ #include "LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "nr_rrc_config.h" -#define false 0 -#define true 1 - void fix_servingcellconfigdedicated(NR_ServingCellConfig_t *scd) { int b = 0; @@ -85,9 +82,9 @@ void fix_servingcellconfigdedicated(NR_ServingCellConfig_t *scd) { void fill_default_nsa_downlinkBWP(NR_BWP_Downlink_t *bwp, long bwp_loop, - NR_CellGroupConfig_t *secondaryCellGroup, - NR_ServingCellConfig_t *servingcellconfigdedicated, - NR_ServingCellConfigCommon_t *servingcellconfigcommon, + const NR_CellGroupConfig_t *secondaryCellGroup, + const NR_ServingCellConfig_t *servingcellconfigdedicated, + const NR_ServingCellConfigCommon_t *servingcellconfigcommon, const gNB_RrcConfigurationReq *configuration, NR_UE_NR_Capability_t *uecap, int dl_antenna_ports, @@ -337,128 +334,26 @@ void fill_default_nsa_uplinkBWP(NR_BWP_Uplink_t *ubwp, /// BWP dedicated configuration - if (!ubwp->bwp_Dedicated) { + if (!ubwp->bwp_Dedicated) ubwp->bwp_Dedicated = calloc(1,sizeof(*ubwp->bwp_Dedicated)); - } + + int curr_bwp = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + ubwp->bwp_Dedicated->pucch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pucch_Config)); ubwp->bwp_Dedicated->pucch_Config->present = NR_SetupRelease_PUCCH_Config_PR_setup; NR_PUCCH_Config_t *pucch_Config = calloc(1,sizeof(*pucch_Config)); ubwp->bwp_Dedicated->pucch_Config->choice.setup=pucch_Config; + pucch_Config->resourceSetToAddModList = calloc(1,sizeof(*pucch_Config->resourceSetToAddModList)); pucch_Config->resourceSetToReleaseList = NULL; - NR_PUCCH_ResourceSet_t *pucchresset0=calloc(1,sizeof(*pucchresset0)); - NR_PUCCH_ResourceSet_t *pucchresset1=calloc(1,sizeof(*pucchresset1)); - pucchresset0->pucch_ResourceSetId = 0; - NR_PUCCH_ResourceId_t *pucchresset0id0=calloc(1,sizeof(*pucchresset0id0)); - *pucchresset0id0=1; - ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id0); - pucchresset0->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset0); - - pucchresset1->pucch_ResourceSetId = 1; - NR_PUCCH_ResourceId_t *pucchresset1id0=calloc(1,sizeof(*pucchresset1id0)); - *pucchresset1id0=2; - ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id0); - pucchresset1->maxPayloadSize=NULL; - ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset1); - pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList)); pucch_Config->resourceToReleaseList = NULL; - NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0)); - NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2)); - - int curr_bwp = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + config_pucch_resset0(pucch_Config, uid, curr_bwp, NULL); + config_pucch_resset1(pucch_Config, NULL); + set_pucch_power_config(pucch_Config, configuration->do_CSIRS); - pucchres0->pucch_ResourceId=1; - pucchres0->startingPRB= (8 + uid) % curr_bwp; - pucchres0->intraSlotFrequencyHopping=NULL; - pucchres0->secondHopPRB=NULL; - pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0; - pucchres0->format.choice.format0=calloc(1,sizeof(*pucchres0->format.choice.format0)); - pucchres0->format.choice.format0->initialCyclicShift=0; - pucchres0->format.choice.format0->nrofSymbols=1; - pucchres0->format.choice.format0->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0); - - pucchres2->pucch_ResourceId=2; - pucchres2->startingPRB=0; - pucchres2->intraSlotFrequencyHopping=NULL; - pucchres2->secondHopPRB=NULL; - pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2; - pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2)); - pucchres2->format.choice.format2->nrofPRBs=8; - pucchres2->format.choice.format2->nrofSymbols=1; - pucchres2->format.choice.format2->startingSymbolIndex=13; - ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2); - - pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2)); - pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup; - NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2)); - pucch_Config->format2->choice.setup = pucchfmt2; - pucchfmt2->interslotFrequencyHopping=NULL; - pucchfmt2->additionalDMRS=NULL; - pucchfmt2->maxCodeRate=calloc(1,sizeof(*pucchfmt2->maxCodeRate)); - *pucchfmt2->maxCodeRate=NR_PUCCH_MaxCodeRate_zeroDot35; - pucchfmt2->nrofSlots=NULL; - pucchfmt2->pi2BPSK=NULL; - pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI)); - *pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true; - - // for scheduling requestresource - pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList)); - NR_SchedulingRequestResourceConfig_t *schedulingRequestResourceConfig = calloc(1,sizeof(*schedulingRequestResourceConfig)); - schedulingRequestResourceConfig->schedulingRequestResourceId = 1; - schedulingRequestResourceConfig->schedulingRequestID = 0; - schedulingRequestResourceConfig->periodicityAndOffset = calloc(1,sizeof(*schedulingRequestResourceConfig->periodicityAndOffset)); - schedulingRequestResourceConfig->periodicityAndOffset->present = NR_SchedulingRequestResourceConfig__periodicityAndOffset_PR_sl10; - schedulingRequestResourceConfig->periodicityAndOffset->choice.sl10 = 7; - schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource)); - *schedulingRequestResourceConfig->resource = 1; - ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig); - - pucch_Config->schedulingRequestResourceToReleaseList=NULL; - pucch_Config->multi_CSI_PUCCH_ResourceList=NULL; - pucch_Config->dl_DataToUL_ACK = calloc(1,sizeof(*pucch_Config->dl_DataToUL_ACK)); - long *delay[8]; - for (int i=0;i<8;i++) { - delay[i] = calloc(1,sizeof(*delay[i])); - *delay[i] = i + configuration->minRXTXTIME; - ASN_SEQUENCE_ADD(&pucch_Config->dl_DataToUL_ACK->list,delay[i]); - } - pucch_Config->spatialRelationInfoToAddModList = calloc(1,sizeof(*pucch_Config->spatialRelationInfoToAddModList)); - NR_PUCCH_SpatialRelationInfo_t *pucchspatial = calloc(1,sizeof(*pucchspatial)); - pucchspatial->pucch_SpatialRelationInfoId = 1; - pucchspatial->servingCellId = NULL; - if(configuration->do_CSIRS) { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_csi_RS_Index; - pucchspatial->referenceSignal.choice.csi_RS_Index = 0; - } - else { - pucchspatial->referenceSignal.present = NR_PUCCH_SpatialRelationInfo__referenceSignal_PR_ssb_Index; - pucchspatial->referenceSignal.choice.ssb_Index = 0; - } - pucchspatial->pucch_PathlossReferenceRS_Id = 0; - pucchspatial->p0_PUCCH_Id = 1; - pucchspatial->closedLoopIndex = NR_PUCCH_SpatialRelationInfo__closedLoopIndex_i0; - ASN_SEQUENCE_ADD(&pucch_Config->spatialRelationInfoToAddModList->list,pucchspatial); - pucch_Config->spatialRelationInfoToReleaseList=NULL; - pucch_Config->pucch_PowerControl=calloc(1,sizeof(*pucch_Config->pucch_PowerControl)); - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f0 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f1 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f2 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f3 = 0; - pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4 = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4)); - *pucch_Config->pucch_PowerControl->deltaF_PUCCH_f4 = 0; - pucch_Config->pucch_PowerControl->p0_Set = calloc(1,sizeof(*pucch_Config->pucch_PowerControl->p0_Set)); - NR_P0_PUCCH_t *p00 = calloc(1,sizeof(*p00)); - p00->p0_PUCCH_Id=1; - p00->p0_PUCCH_Value = 0; - ASN_SEQUENCE_ADD(&pucch_Config->pucch_PowerControl->p0_Set->list,p00); - pucch_Config->pucch_PowerControl->pathlossReferenceRSs = NULL; + scheduling_request_config(servingcellconfigcommon, pucch_Config); + set_dl_DataToUL_ACK(pucch_Config, configuration->minRXTXTIME); ubwp->bwp_Dedicated->pusch_Config = calloc(1,sizeof(*ubwp->bwp_Dedicated->pusch_Config)); ubwp->bwp_Dedicated->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup; @@ -648,40 +543,33 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->rlc_BearerToAddModList = calloc(1,sizeof(*secondaryCellGroup->rlc_BearerToAddModList)); ASN_SEQUENCE_ADD(&secondaryCellGroup->rlc_BearerToAddModList->list, RLC_BearerConfig); - secondaryCellGroup->mac_CellGroupConfig=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig)); - secondaryCellGroup->mac_CellGroupConfig->drx_Config = NULL; - secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig)); - secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList)); - NR_SchedulingRequestToAddMod_t *SchedulingRequestConf = calloc(1,sizeof(*SchedulingRequestConf)); - SchedulingRequestConf->schedulingRequestId = 0; //Could be changed - SchedulingRequestConf->sr_ProhibitTimer = calloc(1,sizeof(*SchedulingRequestConf->sr_ProhibitTimer)); - *SchedulingRequestConf->sr_ProhibitTimer = NR_SchedulingRequestToAddMod__sr_ProhibitTimer_ms16; - SchedulingRequestConf->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n32; - ASN_SEQUENCE_ADD(&secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list,SchedulingRequestConf); - secondaryCellGroup->mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToReleaseList = NULL; - - secondaryCellGroup->mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->bsr_Config)); - secondaryCellGroup->mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; - secondaryCellGroup->mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf160; - secondaryCellGroup->mac_CellGroupConfig->tag_Config=calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config)); - secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; - secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList)); + NR_MAC_CellGroupConfig_t *mac_CellGroupConfig = secondaryCellGroup->mac_CellGroupConfig; + + mac_CellGroupConfig=calloc(1,sizeof(*mac_CellGroupConfig)); + mac_CellGroupConfig->drx_Config = NULL; + + mac_CellGroupConfig->bsr_Config=calloc(1,sizeof(*mac_CellGroupConfig->bsr_Config)); + mac_CellGroupConfig->bsr_Config->periodicBSR_Timer = NR_BSR_Config__periodicBSR_Timer_sf10; + mac_CellGroupConfig->bsr_Config->retxBSR_Timer = NR_BSR_Config__retxBSR_Timer_sf160; + mac_CellGroupConfig->tag_Config=calloc(1,sizeof(*mac_CellGroupConfig->tag_Config)); + mac_CellGroupConfig->tag_Config->tag_ToReleaseList = NULL; + mac_CellGroupConfig->tag_Config->tag_ToAddModList = calloc(1,sizeof(*mac_CellGroupConfig->tag_Config->tag_ToAddModList)); struct NR_TAG *tag=calloc(1,sizeof(*tag)); tag->tag_Id = 0; tag->timeAlignmentTimer = NR_TimeAlignmentTimer_infinity; - ASN_SEQUENCE_ADD(&secondaryCellGroup->mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag); - secondaryCellGroup->mac_CellGroupConfig->phr_Config = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->phr_Config)); - secondaryCellGroup->mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup = calloc(1,sizeof(*secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup)); - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf20; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf0; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB3; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->multiplePHR=false; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->dummy=false; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_Type2OtherCell = false; - secondaryCellGroup->mac_CellGroupConfig->phr_Config->choice.setup->phr_ModeOtherCG = NR_PHR_Config__phr_ModeOtherCG_real; - secondaryCellGroup->mac_CellGroupConfig->skipUplinkTxDynamic=false; - secondaryCellGroup->mac_CellGroupConfig->ext1 = NULL; + ASN_SEQUENCE_ADD(&mac_CellGroupConfig->tag_Config->tag_ToAddModList->list,tag); + mac_CellGroupConfig->phr_Config = calloc(1,sizeof(*mac_CellGroupConfig->phr_Config)); + mac_CellGroupConfig->phr_Config->present = NR_SetupRelease_PHR_Config_PR_setup; + mac_CellGroupConfig->phr_Config->choice.setup = calloc(1,sizeof(*mac_CellGroupConfig->phr_Config->choice.setup)); + mac_CellGroupConfig->phr_Config->choice.setup->phr_PeriodicTimer = NR_PHR_Config__phr_PeriodicTimer_sf20; + mac_CellGroupConfig->phr_Config->choice.setup->phr_ProhibitTimer = NR_PHR_Config__phr_ProhibitTimer_sf0; + mac_CellGroupConfig->phr_Config->choice.setup->phr_Tx_PowerFactorChange = NR_PHR_Config__phr_Tx_PowerFactorChange_dB3; + mac_CellGroupConfig->phr_Config->choice.setup->multiplePHR=false; + mac_CellGroupConfig->phr_Config->choice.setup->dummy=false; + mac_CellGroupConfig->phr_Config->choice.setup->phr_Type2OtherCell = false; + mac_CellGroupConfig->phr_Config->choice.setup->phr_ModeOtherCG = NR_PHR_Config__phr_ModeOtherCG_real; + mac_CellGroupConfig->skipUplinkTxDynamic=false; + mac_CellGroupConfig->ext1 = NULL; secondaryCellGroup->physicalCellGroupConfig = calloc(1,sizeof(*secondaryCellGroup->physicalCellGroupConfig)); secondaryCellGroup->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUCCH=NULL; secondaryCellGroup->physicalCellGroupConfig->harq_ACK_SpatialBundlingPUSCH=NULL; @@ -1140,6 +1028,14 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList= NULL; secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToReleaseList = NULL; + mac_CellGroupConfig->schedulingRequestConfig = calloc(1, sizeof(*mac_CellGroupConfig->schedulingRequestConfig)); + mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList = CALLOC(1,sizeof(*mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList)); + struct NR_SchedulingRequestToAddMod *schedulingrequestlist = CALLOC(1,sizeof(*schedulingrequestlist)); + schedulingrequestlist->schedulingRequestId = 0; + schedulingrequestlist->sr_ProhibitTimer = NULL; + schedulingrequestlist->sr_TransMax = NR_SchedulingRequestToAddMod__sr_TransMax_n64; + ASN_SEQUENCE_ADD(&(mac_CellGroupConfig->schedulingRequestConfig->schedulingRequestToAddModList->list),schedulingrequestlist); + secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig)); NR_PUSCH_ServingCellConfig_t *pusch_scc = calloc(1,sizeof(*pusch_scc)); secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->pusch_ServingCellConfig->present = NR_SetupRelease_PUSCH_ServingCellConfig_PR_setup; diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index 6f0c7fc27fa2c868ec456b0a4aa539fdd79ba774..8907ff315ad993949465424695ae3194dfaaeb84 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -34,6 +34,7 @@ #include "rrc_proto.h" #include "assertions.h" #include "rrc_vars.h" +#include "MAC/mac.h" typedef uint32_t channel_t; @@ -181,6 +182,6 @@ rrc_data_req_nr_ue( TASK_PDCP_UE, ctxt_pP->instance, message_p); - return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. + return true; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway. } diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 50ec32772de354c87f7722aebe23abbe918238a0..bf4f053ba6fe5ec3d9023550d2e4e91bef7c2713 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1320,11 +1320,11 @@ nr_rrc_ue_process_masterCellGroup( //TODO (perform SCell addition/modification as specified in 5.3.5.5.9) } - if( cellGroupConfig->ext2->bh_RLC_ChannelToReleaseList_r16 != NULL){ + if(cellGroupConfig->ext2 != NULL && cellGroupConfig->ext2->bh_RLC_ChannelToReleaseList_r16 != NULL){ //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11) } - if( cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){ + if(cellGroupConfig->ext2 != NULL && cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){ //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11) } } @@ -1342,12 +1342,6 @@ static void rrc_ue_generate_RRCSetupComplete( int nas_msg_length; if (AMF_MODE_ENABLED) { -#if defined(ITTI_SIM) - as_nas_info_t initialNasMsg; - generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id); - nas_msg = (char*)initialNasMsg.data; - nas_msg_length = initialNasMsg.length; -#else if (get_softmodem_params()->sa) { as_nas_info_t initialNasMsg; generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id); @@ -1357,7 +1351,6 @@ static void rrc_ue_generate_RRCSetupComplete( nas_msg = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data; nas_msg_length = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length; } -#endif } else { nas_msg = nr_nas_attach_req_imsi; nas_msg_length = sizeof(nr_nas_attach_req_imsi); @@ -1381,18 +1374,6 @@ static void rrc_ue_generate_RRCSetupComplete( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE, TASK_RRC_GNB_SIM, size); - memcpy (message_buffer, buffer, size); - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - UE_RRC_DCCH_DATA_IND (message_p).rbid = 1; - UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - UE_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); -#endif } int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ){ @@ -1711,19 +1692,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB } LOG_T(NR_RRC, "\n"); - #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM, - (enc_rval.encoded + 7) / 8); - memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8); - - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); - #else rrc_data_req_nr_ue (ctxt_pP, DCCH, nr_rrc_mui++, @@ -1731,7 +1699,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB (enc_rval.encoded + 7) / 8, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - #endif } else LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n", securityModeCommand->criticalExtensions.present); @@ -1777,19 +1744,6 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB //printf("\n"); /*UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.Payload[i] = taus()&0xff; UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.payload_size =i; */ - -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM, - NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size); - memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload, - NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size); - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_CCCH_DATA_IND); - GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_CCCH_DATA_IND (message_p).size = NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, gNB_index, message_p); -#endif } } @@ -2014,7 +1968,7 @@ nr_rrc_ue_establish_srb2( int i, cnt; if( radioBearerConfig->srb3_ToRelease != NULL){ - if( *radioBearerConfig->srb3_ToRelease == TRUE){ + if( *radioBearerConfig->srb3_ToRelease == true){ //TODO (release the PDCP entity and the srb-Identity of the SRB3.) } } @@ -2254,19 +2208,6 @@ nr_rrc_ue_establish_srb2( nr_rrc_mui, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), DCCH); - #ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,size); - memcpy (message_buffer, buffer, size); - - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - UE_RRC_DCCH_DATA_IND (message_p).size = size; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); - - #else rrc_data_req_nr_ue ( ctxt_pP, DCCH, @@ -2275,8 +2216,6 @@ nr_rrc_ue_establish_srb2( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - #endif - } // from NR SRB1 @@ -2523,22 +2462,6 @@ nr_rrc_ue_establish_srb2( length = do_NR_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data); /* Transfer data to PDCP */ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0,0); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length); - memcpy (message_buffer, buffer, length); - - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) - UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - else - UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH1; - UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - UE_RRC_DCCH_DATA_IND (message_p).size = length; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt.instance, message_p); - -#else // check if SRB2 is created, if yes request data_req on DCCH1 (SRB2) if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) { rrc_data_req_nr_ue (&ctxt, @@ -2555,7 +2478,6 @@ nr_rrc_ue_establish_srb2( length, buffer, PDCP_TRANSMISSION_MODE_CONTROL); } -#endif break; } @@ -2699,19 +2621,6 @@ nr_rrc_ue_process_ueCapabilityEnquiry( } LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM, - (enc_rval.encoded + 7) / 8); - memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8); - - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - GNB_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - GNB_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - GNB_RRC_DCCH_DATA_IND (message_p).size = (enc_rval.encoded + 7) / 8; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); -#else rrc_data_req_nr_ue ( ctxt_pP, DCCH, @@ -2720,7 +2629,6 @@ nr_rrc_ue_process_ueCapabilityEnquiry( (enc_rval.encoded + 7) / 8, buffer, PDCP_TRANSMISSION_MODE_CONTROL); -#endif } } } @@ -2739,19 +2647,6 @@ nr_rrc_ue_generate_rrcReestablishmentComplete( rrcReestablishment->rrc_TransactionIdentifier); LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes%d, gNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame, length, gNB_index); -#ifdef ITTI_SIM - MessageDef *message_p; - uint8_t *message_buffer; - message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length); - memcpy (message_buffer, buffer, length); - - message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND); - UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH; - UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer; - UE_RRC_DCCH_DATA_IND (message_p).size = length; - itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p); - -#endif } void *recv_msgs_from_lte_ue(void *args_p) diff --git a/openair2/SDAP/nr_sdap/nr_sdap.c b/openair2/SDAP/nr_sdap/nr_sdap.c index 74ef93aff743fa9929e9c0d3aa2227dc5c45ec5b..6457843ae06b003f9ac3d07926cb0e8c601b60a1 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap.c +++ b/openair2/SDAP/nr_sdap/nr_sdap.c @@ -21,19 +21,22 @@ #include "nr_sdap.h" -boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p, - const srb_flag_t srb_flag, - const rb_id_t rb_id, - const mui_t mui, - const confirm_t confirm, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t pt_mode, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi, - const int pdusession_id) { +uint8_t nas_qfi; +uint8_t nas_pduid; + +bool sdap_data_req(protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi, + const int pdusession_id) { nr_sdap_entity_t *sdap_entity; sdap_entity = nr_sdap_get_entity(ctxt_p->rnti, pdusession_id); @@ -42,19 +45,19 @@ boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p, return 0; } - boolean_t ret = sdap_entity->tx_entity(sdap_entity, - ctxt_p, - srb_flag, - rb_id, - mui, - confirm, - sdu_buffer_size, - sdu_buffer, - pt_mode, - sourceL2Id, - destinationL2Id, - qfi, - rqi); + bool ret = sdap_entity->tx_entity(sdap_entity, + ctxt_p, + srb_flag, + rb_id, + mui, + confirm, + sdu_buffer_size, + sdu_buffer, + pt_mode, + sourceL2Id, + destinationL2Id, + qfi, + rqi); return ret; } @@ -84,3 +87,9 @@ void sdap_data_ind(rb_id_t pdcp_entity, buf, size); } + +void set_qfi_pduid(uint8_t qfi, uint8_t pduid){ + nas_qfi = qfi; + nas_pduid = pduid; + return; +} diff --git a/openair2/SDAP/nr_sdap/nr_sdap.h b/openair2/SDAP/nr_sdap/nr_sdap.h index cd702cfd7f39d2b6698842b3fa1b643458ba0710..ea4fe7f74dc819c4c83b22a186d8ed04dc53fafd 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap.h +++ b/openair2/SDAP/nr_sdap/nr_sdap.h @@ -32,20 +32,19 @@ * Downlink - gNB * Uplink - nrUE */ -boolean_t sdap_data_req(protocol_ctxt_t *ctxt_p, - const srb_flag_t srb_flag, - const rb_id_t rb_id, - const mui_t mui, - const confirm_t confirm, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t pt_mode, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi, - const int pdusession_id - ); +bool sdap_data_req(protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi, + const int pdusession_id); /* * TS 37.324 4.4 Functions @@ -63,4 +62,6 @@ void sdap_data_ind(rb_id_t pdcp_entity, int size ); +void set_qfi_pduid(uint8_t qfi, uint8_t pduid); + #endif diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c index 79532748d2895107a9a0e6717af3cb62c0987e59..5e3627296c56b62a15e3a33bdd390cb746913168 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c @@ -46,23 +46,22 @@ void nr_pdcp_submit_sdap_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_u return; } -static boolean_t nr_sdap_tx_entity(nr_sdap_entity_t *entity, - protocol_ctxt_t *ctxt_p, - const srb_flag_t srb_flag, - const rb_id_t rb_id, - const mui_t mui, - const confirm_t confirm, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t pt_mode, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi - ) { +static bool nr_sdap_tx_entity(nr_sdap_entity_t *entity, + protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi) { /* The offset of the SDAP header, it might be 0 if the has_sdap is not true in the pdcp entity. */ int offset=0; - boolean_t ret=false; + bool ret = false; /*Hardcode DRB ID given from upper layer (ue/enb_tun_read_thread rb_id), it will change if we have SDAP*/ rb_id_t sdap_drb_id = rb_id; int pdcp_ent_has_sdap = 0; @@ -297,7 +296,7 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity, } } -void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap){ +void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, bool hasSdap) { if(qfi < SDAP_MAX_QFI && qfi > SDAP_MAP_RULE_EMPTY && drb > 0 && @@ -390,7 +389,7 @@ void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity, nr_sdap_entity_t *new_nr_sdap_entity(int has_sdap, uint16_t rnti, int pdusession_id, - boolean_t is_defaultDRB, + bool is_defaultDRB, uint8_t drb_identity, NR_QFI_t *mapped_qfi_2_add, uint8_t mappedQFIs2AddCount) diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.h b/openair2/SDAP/nr_sdap/nr_sdap_entity.h index b46e5bf4e3462bef98b65b5e2e799b14dc7b6319..635289d4d48cfc4f7d41564f87c8668236bc19a6 100644 --- a/openair2/SDAP/nr_sdap/nr_sdap_entity.h +++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.h @@ -64,7 +64,7 @@ typedef struct nr_sdap_ul_hdr_s { typedef struct qfi2drb_s { rb_id_t drb_id; - boolean_t hasSdap; + bool hasSdap; } qfi2drb_t; void nr_pdcp_submit_sdap_ctrl_pdu(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu); @@ -75,7 +75,7 @@ typedef struct nr_sdap_entity_s { int pdusession_id; qfi2drb_t qfi2drb_table[SDAP_MAX_QFI]; - void (*qfi2drb_map_update)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap); + void (*qfi2drb_map_update)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t drb, bool hasSdap); void (*qfi2drb_map_delete)(struct nr_sdap_entity_s *entity, uint8_t qfi); rb_id_t (*qfi2drb_map)(struct nr_sdap_entity_s *entity, uint8_t qfi, rb_id_t upper_layer_rb_id); @@ -84,20 +84,19 @@ typedef struct nr_sdap_entity_s { void (*sdap_submit_ctrl_pdu)(int rnti, rb_id_t sdap_ctrl_pdu_drb, nr_sdap_ul_hdr_t ctrl_pdu); - boolean_t (*tx_entity)(struct nr_sdap_entity_s *entity, - protocol_ctxt_t *ctxt_p, - const srb_flag_t srb_flag, - const rb_id_t rb_id, - const mui_t mui, - const confirm_t confirm, - const sdu_size_t sdu_buffer_size, - unsigned char *const sdu_buffer, - const pdcp_transmission_mode_t pt_mode, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi - ); + bool (*tx_entity)(struct nr_sdap_entity_s *entity, + protocol_ctxt_t *ctxt_p, + const srb_flag_t srb_flag, + const rb_id_t rb_id, + const mui_t mui, + const confirm_t confirm, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t pt_mode, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi); void (*rx_entity)(struct nr_sdap_entity_s *entity, rb_id_t pdcp_entity, @@ -114,7 +113,7 @@ typedef struct nr_sdap_entity_s { } nr_sdap_entity_t; /* QFI to DRB Mapping Related Function */ -void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, boolean_t hasSdap); +void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, uint8_t qfi, rb_id_t drb, bool hasSdap); /* QFI to DRB Mapping Related Function */ void nr_sdap_qfi2drb_map_del(nr_sdap_entity_t *entity, uint8_t qfi); @@ -168,7 +167,7 @@ void nr_sdap_ue_qfi2drb_config(nr_sdap_entity_t *existing_sdap_entity, nr_sdap_entity_t *new_nr_sdap_entity(int has_sdap, uint16_t rnti, int pdusession_id, - boolean_t is_defaultDRB, + bool is_defaultDRB, uint8_t default_DRB, NR_QFI_t *mapped_qfi_2_add, uint8_t mappedQFIs2AddCount); diff --git a/openair2/SIMULATION/NR_RRC/itti_sim.c b/openair2/SIMULATION/NR_RRC/itti_sim.c deleted file mode 100644 index a6ac444e45ba11bb458715aadcf6d69d8be60798..0000000000000000000000000000000000000000 --- a/openair2/SIMULATION/NR_RRC/itti_sim.c +++ /dev/null @@ -1,664 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (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.openairinterface.org/?page_id=698 - * - * 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. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! \file itti_sim.c - * \brief simulator for itti message from node to UE - * \author Yoshio INOUE, Masayuki HARADA - * \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com - * \date 2020 - * \version 0.1 - */ - - -#include <sched.h> - - -#include "T.h" - -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all -#include <common/utils/assertions.h> - -#include "common/ran_context.h" - -#include "common/config/config_userapi.h" -#include "common/utils/load_module_shlib.h" -#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all - -#include "PHY/phy_vars.h" -#include "SCHED/sched_common_vars.h" -#include "LAYER2/MAC/mac_vars.h" -#include "RRC/LTE/rrc_vars.h" -#include "gnb_config.h" -#include "SIMULATION/TOOLS/sim.h" - -#ifdef SMBV -#include "PHY/TOOLS/smbv.h" -unsigned short config_frames[4] = {2,9,11,13}; -#endif - -#include "common/utils/LOG/log.h" -#include "common/utils/LOG/vcd_signal_dumper.h" -#include "UTIL/OPT/opt.h" - -#include "intertask_interface.h" - - -#include "system.h" -#include <openair2/GNB_APP/gnb_app.h> -#include "PHY/TOOLS/phy_scope_interface.h" -#include "PHY/TOOLS/nr_phy_scope.h" -#include "stats.h" -#include "nr-softmodem.h" -#include "executables/softmodem-common.h" -#include "executables/thread-common.h" -#include "NB_IoT_interface.h" -#include "x2ap_eNB.h" -#include "ngap_gNB.h" -#include "RRC/NR_UE/rrc_proto.h" -#include "RRC/NR_UE/rrc_vars.h" -#include "openair3/NAS/UE/nas_ue_task.h" -#include <executables/split_headers.h> -#include <executables/nr-uesoftmodem.h> -#if ITTI_SIM -#include "nr_nas_msg_sim.h" -#endif - -pthread_cond_t nfapi_sync_cond; -pthread_mutex_t nfapi_sync_mutex; -int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex - -uint32_t timing_advance = 0; -uint64_t num_missed_slots=0; - -int split73=0; -void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) { - AssertFatal(false, "Must not be called in this context\n"); -} -void sendFs6Ulharq(enum pckType type, int UEid, PHY_VARS_eNB *eNB, LTE_eNB_UCI *uci, int frame, int subframe, uint8_t *harq_ack, uint8_t tdd_mapping_mode, uint16_t tdd_multiplexing_mask, uint16_t rnti, int32_t stat) { - AssertFatal(false, "Must not be called in this context\n"); -} - -nrUE_params_t nrUE_params; -nrUE_params_t *get_nrUE_params(void) { - return &nrUE_params; -} - -void processSlotTX(void *arg) {} - -THREAD_STRUCT thread_struct; -pthread_cond_t sync_cond; -pthread_mutex_t sync_mutex; -int sync_var=-1; //!< protected by mutex \ref sync_mutex. -int config_sync_var=-1; - -openair0_config_t openair0_cfg[MAX_CARDS]; - -//volatile int start_gNB = 0; -volatile int oai_exit = 0; - -//static int wait_for_sync = 0; - -unsigned int mmapped_dma=0; -int single_thread_flag=1; - -int8_t threequarter_fs=0; - -uint64_t downlink_frequency[MAX_NUM_CCs][4]; -int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; - -//Temp fix for inexistent NR upper layer -unsigned char NB_gNB_INST = 1; - - -int UE_scan = 1; -int UE_scan_carrier = 0; -runmode_t mode = normal_txrx; -static double snr_dB=20; - -FILE *input_fd=NULL; - -int chain_offset=0; - - -uint8_t dci_Format = 0; -uint8_t agregation_Level =0xFF; - -uint8_t nb_antenna_tx = 1; -uint8_t nb_antenna_rx = 1; - -char ref[128] = "internal"; -char channels[128] = "0"; - -int otg_enabled; - -extern void *udp_eNB_task(void *args_p); - -int transmission_mode=1; -int emulate_rf = 0; -int numerology = 0; - - -double cpuf; - -extern char uecap_xer[1024]; -char uecap_xer_in=0; - -/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed - * this is very hackish - find a proper solution - */ -uint8_t abstraction_flag=0; - -/* forward declarations */ -void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); - -/*---------------------BMC: timespec helpers -----------------------------*/ - -struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; -struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 }; - -struct timespec clock_difftime(struct timespec start, struct timespec end) { - struct timespec temp; - - if ((end.tv_nsec-start.tv_nsec)<0) { - temp.tv_sec = end.tv_sec-start.tv_sec-1; - temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; - } else { - temp.tv_sec = end.tv_sec-start.tv_sec; - temp.tv_nsec = end.tv_nsec-start.tv_nsec; - } - - return temp; -} - - - -#define KNRM "\x1B[0m" -#define KRED "\x1B[31m" -#define KGRN "\x1B[32m" -#define KBLU "\x1B[34m" -#define RESET "\033[0m" - - -void exit_function(const char *file, const char *function, const int line, const char *s) { - int ru_id; - - if (s != NULL) { - printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); - } - - oai_exit = 1; - - if (RC.ru == NULL) - exit(-1); // likely init not completed, prevent crash or hang, exit now... - - for (ru_id=0; ru_id<RC.nb_RU; ru_id++) { - if (RC.ru[ru_id] && RC.ru[ru_id]->rfdevice.trx_end_func) { - RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice); - RC.ru[ru_id]->rfdevice.trx_end_func = NULL; - } - - if (RC.ru[ru_id] && RC.ru[ru_id]->ifdevice.trx_end_func) { - RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice); - RC.ru[ru_id]->ifdevice.trx_end_func = NULL; - } - } - - sleep(1); //allow lte-softmodem threads to exit first - exit(1); -} - -void wait_gNBs(void) { - int i; - int waiting=1; - - while (waiting==1) { - printf("Waiting for gNB L1 instances to all get configured ... sleeping 50ms (nb_nr_sL1_inst %d)\n",RC.nb_nr_L1_inst); - usleep(50*1000); - waiting=0; - - for (i=0; i<RC.nb_nr_L1_inst; i++) { - - if (RC.gNB[i]->configured==0) { - waiting=1; - break; - } - } - } - - printf("gNB L1 are configured\n"); -} - -void wait_RUs(void) { - LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask); - // wait for all RUs to be configured over fronthaul - pthread_mutex_lock(&RC.ru_mutex); - - while (RC.ru_mask>0) { - pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex); - printf("RC.ru_mask:%02lx\n", RC.ru_mask); - } - - pthread_mutex_unlock(&RC.ru_mutex); - LOG_I(PHY,"RUs configured\n"); -} - - -int stop_L1L2(module_id_t gnb_id) { - return 0; -} - -int restart_L1L2(module_id_t gnb_id) { - return 0; -} - -int create_gNB_tasks(uint32_t gnb_nb) { - LOG_D(GNB_APP, "%s(gnb_nb:%d)\n", __FUNCTION__, gnb_nb); - itti_wait_ready(1); - - - if (gnb_nb > 0) { - if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){ - LOG_E(SCTP, "Create task for SCTP failed\n"); - return -1; - } - if (is_x2ap_enabled()) { - if(itti_create_task(TASK_X2AP, x2ap_task, NULL) < 0){ - LOG_E(X2AP, "Create task for X2AP failed\n"); - } - } - else { - LOG_I(X2AP, "X2AP is disabled.\n"); - } - } - - if (AMF_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0 && get_softmodem_params()->sa==0)) { - if (gnb_nb > 0) { - if (itti_create_task (TASK_NGAP, ngap_gNB_task, NULL) < 0) { - LOG_E(S1AP, "Create task for NGAP failed\n"); - return -1; - } - - - if(!emulate_rf){ - if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { - LOG_E(UDP_, "Create task for UDP failed\n"); - return -1; - } - } - - if (itti_create_task (TASK_GTPV1_U, &nr_gtpv1u_gNB_task, NULL) < 0) { - LOG_E(GTPU, "Create task for GTPV1U failed\n"); - return -1; - } - } - } - - - if (gnb_nb > 0) { - if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { - LOG_E(GNB_APP, "Create task for gNB APP failed\n"); - return -1; - } - LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); - - if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { - LOG_E(NR_RRC, "Create task for NR RRC gNB failed\n"); - return -1; - } - } - - return 0; -} - - -static void get_options(void) { - - - paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; - - CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); - get_common_options(SOFTMODEM_GNB_BIT ); - config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); - CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP); - - - - - if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { - memset((void *)&RC,0,sizeof(RC)); - /* Read RC configuration file */ - NRRCConfig(); - NB_gNB_INST = RC.nb_nr_inst; - NB_RU = RC.nb_RU; - printf("Configuration: nb_rrc_inst %d, nb_nr_L1_inst %d, nb_ru %hhu\n",NB_gNB_INST,RC.nb_nr_L1_inst,NB_RU); - } - -} - - -void set_default_frame_parms(nfapi_nr_config_request_scf_t *config[MAX_NUM_CCs], - NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) -{ - for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) { - frame_parms[CC_id] = (NR_DL_FRAME_PARMS *) malloc(sizeof(NR_DL_FRAME_PARMS)); - config[CC_id] = (nfapi_nr_config_request_scf_t *) malloc(sizeof(nfapi_nr_config_request_scf_t)); - config[CC_id]->ssb_config.scs_common.value = 1; - config[CC_id]->cell_config.frame_duplex_type.value = 1; //FDD - config[CC_id]->carrier_config.dl_grid_size[1].value = 106; - config[CC_id]->carrier_config.ul_grid_size[1].value = 106; - config[CC_id]->cell_config.phy_cell_id.value = 0; - } -} - -/* - * helper function to terminate a certain ITTI task - */ -void terminate_task(task_id_t task_id, module_id_t mod_id) { - LOG_I(GNB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id); - MessageDef *msg; - msg = itti_alloc_new_message (ENB_APP, 0, TERMINATE_MESSAGE); - itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg); -} - -//extern void free_transport(PHY_VARS_gNB *); -extern void nr_phy_free_RU(RU_t *); - -statis void init_pdcp(void) { - //if (!NODE_IS_DU(RC.rrc[0]->node_type)) { - pdcp_layer_init(); - uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ? - (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; - - if (IS_SOFTMODEM_NOS1) { - printf("IS_SOFTMODEM_NOS1 option enabled \n"); - pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; - } - - pdcp_module_init(pdcp_initmask, 0); - - pdcp_set_rlc_data_req_func(rlc_data_req); - pdcp_set_pdcp_data_ind_func(pdcp_data_ind); -} - - -int create_tasks_nrue(uint32_t ue_nb) { - LOG_D(ENB_APP, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb); - itti_wait_ready(1); - - if (ue_nb > 0) { - LOG_D(NR_RRC, "create TASK_RRC_NRUE\n"); - if (itti_create_task (TASK_RRC_NRUE, rrc_nrue_task, NULL) < 0) { - LOG_E(NR_RRC, "Create task for RRC UE failed\n"); - return -1; - } - - LOG_D(NR_RRC,"create TASK_NAS_NRUE\n"); - if (itti_create_task (TASK_NAS_NRUE, nas_nrue_task, NULL) < 0) { - LOG_E(NR_RRC, "Create task for NAS UE failed\n"); - return -1; - } - } - - - itti_wait_ready(0); - return 0; -} - - -void *itti_sim_ue_rrc_task( void *args_p) { - MessageDef *msg_p, *message_p; - instance_t instance; - unsigned int ue_mod_id; - int result; - itti_mark_task_ready (TASK_RRC_UE_SIM); - - while(1) { - // Wait for a message - itti_receive_msg (TASK_RRC_UE_SIM, &msg_p); - instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); - ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); - - switch (ITTI_MSG_ID(msg_p)) { - case TERMINATE_MESSAGE: - LOG_W(NR_RRC, " *** Exiting RRC thread\n"); - itti_exit_task (); - break; - - case MESSAGE_TEST: - LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); - break; - case GNB_RRC_BCCH_DATA_IND: - message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_MAC_BCCH_DATA_IND); - memset (NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE); - NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu_size = GNB_RRC_BCCH_DATA_IND(msg_p).size; - memcpy (NR_RRC_MAC_BCCH_DATA_IND (message_p).sdu, GNB_RRC_BCCH_DATA_IND(msg_p).sdu, GNB_RRC_BCCH_DATA_IND(msg_p).size); - itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p); - break; - case GNB_RRC_CCCH_DATA_IND: - message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_MAC_CCCH_DATA_IND); - printf("receive GNB_RRC_CCCH_DATA_IND\n"); - memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, GNB_RRC_CCCH_DATA_IND(msg_p).sdu, GNB_RRC_CCCH_DATA_IND(msg_p).size); - NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = GNB_RRC_CCCH_DATA_IND(msg_p).size; - itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p); - break; - case GNB_RRC_DCCH_DATA_IND: - printf("receive GNB_RRC_DCCH_DATA_IND\n"); - message_p = itti_alloc_new_message (TASK_RRC_UE_SIM, 0, NR_RRC_DCCH_DATA_IND); - NR_RRC_DCCH_DATA_IND (message_p).dcch_index = GNB_RRC_DCCH_DATA_IND(msg_p).rbid; - NR_RRC_DCCH_DATA_IND (message_p).sdu_size = GNB_RRC_DCCH_DATA_IND(msg_p).size; - NR_RRC_DCCH_DATA_IND (message_p).sdu_p = GNB_RRC_DCCH_DATA_IND(msg_p).sdu; - itti_send_msg_to_task (TASK_RRC_NRUE, instance, message_p); - break; - default: - LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); - break; - } - - result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - msg_p = NULL; - } -} - - -void *itti_sim_gnb_rrc_task( void *args_p) { - MessageDef *msg_p, *message_p; - instance_t instance; - unsigned int ue_mod_id; - int result; - itti_mark_task_ready (TASK_RRC_GNB_SIM); - - while(1) { - // Wait for a message - itti_receive_msg (TASK_RRC_GNB_SIM, &msg_p); - instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p); - ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance); - - switch (ITTI_MSG_ID(msg_p)) { - case TERMINATE_MESSAGE: - LOG_W(NR_RRC, " *** Exiting RRC thread\n"); - itti_exit_task (); - break; - - case MESSAGE_TEST: - LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); - break; - case UE_RRC_CCCH_DATA_IND: - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, NR_RRC_MAC_CCCH_DATA_IND); - NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu_size = UE_RRC_CCCH_DATA_IND(msg_p).size; - memset (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE); - memcpy (NR_RRC_MAC_CCCH_DATA_IND (message_p).sdu, UE_RRC_CCCH_DATA_IND(msg_p).sdu, UE_RRC_CCCH_DATA_IND(msg_p).size); - itti_send_msg_to_task (TASK_RRC_GNB, instance, message_p); - break; - case UE_RRC_DCCH_DATA_IND: - message_p = itti_alloc_new_message (TASK_RRC_GNB_SIM, 0, NR_RRC_DCCH_DATA_IND); - NR_RRC_DCCH_DATA_IND (message_p).sdu_size = UE_RRC_DCCH_DATA_IND(msg_p).size; - NR_RRC_DCCH_DATA_IND (message_p).dcch_index = UE_RRC_DCCH_DATA_IND(msg_p).rbid; - NR_RRC_DCCH_DATA_IND (message_p).sdu_p = UE_RRC_DCCH_DATA_IND(msg_p).sdu; - itti_send_msg_to_task (TASK_RRC_GNB, instance, message_p); - break; - - default: - LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); - break; - } - - result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - msg_p = NULL; - } -} - - -int main( int argc, char **argv ) -{ - start_background_system(); - - ///static configuration for NR at the moment - if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { - exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); - } - set_softmodem_sighandler(); -#ifdef DEBUG_CONSOLE - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); -#endif - - logInit(); - //set_latency_target(); - printf("Reading in command-line options\n"); - get_options (); - - if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { - fprintf(stderr,"Getting configuration failed\n"); - exit(-1); - } - - AMF_MODE_ENABLED = !IS_SOFTMODEM_NOS1; -// AMF_MODE_ENABLED = 0; - NGAP_CONF_MODE = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test; - -#if T_TRACER - T_Config_Init(); -#endif - //randominit (0); - set_taus_seed (0); - printf("configuring for RAU/RRU\n"); - - if (opp_enabled ==1) { - reset_opp_meas(); - } - - cpuf=get_cpu_freq_GHz(); - itti_init(TASK_MAX, tasks_info); - - init_opt(); - - LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - - if(IS_SOFTMODEM_NOS1) - init_pdcp(); - - if (RC.nb_nr_inst > 0) { - nr_read_config_and_init(); - // don't create if node doesn't connect to RRC/S1/GTP - AssertFatal(create_gNB_tasks(1) == 0,"cannot create ITTI tasks\n"); - for (int gnb_id = 0; gnb_id < RC.nb_nr_inst; gnb_id++) { - MessageDef *msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ); - NRRRC_CONFIGURATION_REQ(msg_p) = RC.nrrrc[gnb_id]->configuration; - itti_send_msg_to_task (TASK_RRC_GNB, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); - } - } else { - printf("No ITTI, Initializing L1\n"); - return 0; - } - - if(itti_create_task (TASK_RRC_GNB_SIM, itti_sim_gnb_rrc_task, NULL) < 0){ - printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode - } - - openair_rrc_top_init_ue_nr("./"); - - if (create_tasks_nrue(1) < 0) { - printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode - } - - if(itti_create_task (TASK_RRC_UE_SIM, itti_sim_ue_rrc_task, NULL) < 0){ - printf("cannot create ITTI tasks\n"); - exit(-1); // need a softer mode - } - - pthread_cond_init(&sync_cond,NULL); - pthread_mutex_init(&sync_mutex, NULL); - - printf("Sending sync to all threads\n"); - pthread_mutex_lock(&sync_mutex); - sync_var=0; - pthread_cond_broadcast(&sync_cond); - pthread_mutex_unlock(&sync_mutex); - // wait for end of program - printf("TYPE <CTRL-C> TO TERMINATE\n"); - - usleep(100000); - protocol_ctxt_t ctxt; - struct rrc_gNB_ue_context_s *ue_context_p = NULL; - - - ue_context_p = rrc_gNB_allocate_new_UE_context(RC.nrrrc[0]); - - if(ue_context_p == NULL){ - printf("ue_context_p == NULL"); - } - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, - 0, - ENB_FLAG_YES, - 0, - 0, - 0); - NR_UE_rrc_inst[ctxt.module_id].Info[0].State = RRC_SI_RECEIVED; - - nr_rrc_ue_generate_RRCSetupRequest(ctxt.module_id, 0); - - printf("Entering ITTI signals handler\n"); - itti_wait_tasks_end(); - printf("Returned from ITTI signal handler\n"); - oai_exit=1; - printf("oai_exit=%d\n",oai_exit); - - printf("stopping MODEM threads\n"); - - - /* release memory used by the RU/gNB threads (incomplete), after all - * threads have been stopped (they partially use the same memory) */ - - pthread_cond_destroy(&sync_cond); - pthread_mutex_destroy(&sync_mutex); - - logClean(); - printf("Bye.\n"); - return 0; -} - - - diff --git a/openair2/UTIL/OMG/defs.h b/openair2/UTIL/OMG/defs.h index 06c9bf6e73fe1a5adc3c2f6022157969ccfd43ce..1102a69cc56a7ee85c825bb2a73de6291d87e7e6 100644 --- a/openair2/UTIL/OMG/defs.h +++ b/openair2/UTIL/OMG/defs.h @@ -29,12 +29,6 @@ #include <stdlib.h> -// TYPEDEFS - -#define true 1 -#define false 0 - -//typedef char bool; #include <stdbool.h> #include "omg_constants.h" diff --git a/openair2/X2AP/x2ap_common.c b/openair2/X2AP/x2ap_common.c index 93a8c3251327b996e2c918f3bc15fe89e244ea92..a687b9066607ff34dc64f1c7bcc021cc5f798f7a 100644 --- a/openair2/X2AP/x2ap_common.c +++ b/openair2/X2AP/x2ap_common.c @@ -31,27 +31,6 @@ #include "x2ap_common.h" #include "X2AP_X2AP-PDU.h" -int asn_debug = 0; -int asn1_xer_print = 0; - -#if defined(EMIT_ASN_DEBUG_EXTERN) -inline void ASN_DEBUG(const char *fmt, ...) -{ - if (asn_debug) { - int adi = asn_debug_indent; - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "[ASN1]"); - - while(adi--) fprintf(stderr, " "); - - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - } -} -#endif - ssize_t x2ap_generate_initiating_message( uint8_t **buffer, uint32_t *length, diff --git a/openair2/X2AP/x2ap_common.h b/openair2/X2AP/x2ap_common.h index a2f903a73725f812b44314e02408ad40ceed145f..e7b86c77b9331bcb8221b9b59b6ee283b56ef1d2 100644 --- a/openair2/X2AP/x2ap_common.h +++ b/openair2/X2AP/x2ap_common.h @@ -18,10 +18,8 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - -#if HAVE_CONFIG_H_ -# include "config.h" -#endif +#ifndef X2AP_COMMON_H_ +#define X2AP_COMMON_H_ #include "X2AP_ProtocolIE-Field.h" #include "X2AP_X2AP-PDU.h" @@ -35,9 +33,6 @@ #include "X2AP_asn_constant.h" #include "intertask_interface.h" -#ifndef X2AP_COMMON_H_ -#define X2AP_COMMON_H_ - /** @defgroup _x2ap_impl_ X2AP Layer Reference Implementation * @ingroup _ref_implementation_ * @{ @@ -52,11 +47,6 @@ # define X2AP_PORT 36422 #endif -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - extern int asn1_xer_print; #if defined(ENB_MODE) diff --git a/openair3/COMMON/security_types.h b/openair3/COMMON/security_types.h index eb55e44d77b8105c7208af1f0c7a2c77338a5b91..5494ffd9941b3afff6e16add034a197e8deb4a18 100644 --- a/openair3/COMMON/security_types.h +++ b/openair3/COMMON/security_types.h @@ -18,10 +18,8 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif +#ifndef SECURITY_TYPES_H_ +#define SECURITY_TYPES_H_ #if !defined(HAVE_UINT128_T) # include <gmp.h> @@ -31,8 +29,6 @@ #include <stdint.h> #include <inttypes.h> -#ifndef SECURITY_TYPES_H_ -#define SECURITY_TYPES_H_ #define RAND_LENGTH_BITS (128) #define RAND_LENGTH_OCTETS (RAND_LENGTH_BITS/8) diff --git a/openair3/M3AP/m3ap_common.c b/openair3/M3AP/m3ap_common.c index 55019976389592985734c4e2c3c4b826792b5fc1..e43275d96cfc05bd2c1affa48d9dc8a41a0d1923 100644 --- a/openair3/M3AP/m3ap_common.c +++ b/openair3/M3AP/m3ap_common.c @@ -31,27 +31,6 @@ #include "m3ap_common.h" #include "M3AP_M3AP-PDU.h" -int asn_debug = 0; -int asn1_xer_print = 0; - -#if defined(EMIT_ASN_DEBUG_EXTERN) -inline void ASN_DEBUG(const char *fmt, ...) -{ - if (asn_debug) { - int adi = asn_debug_indent; - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "[ASN1]"); - - while(adi--) fprintf(stderr, " "); - - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - } -} -#endif - ssize_t m3ap_generate_initiating_message( uint8_t **buffer, uint32_t *length, diff --git a/openair3/M3AP/m3ap_common.h b/openair3/M3AP/m3ap_common.h index 7f68510314fa31b18148a222e7769cdd17990c49..75c60db71a1b165bcfab8aa72ca503bacafda5ba 100644 --- a/openair3/M3AP/m3ap_common.h +++ b/openair3/M3AP/m3ap_common.h @@ -18,10 +18,8 @@ * For more information about the OpenAirInterface (OAI) Software Alliance: * contact@openairinterface.org */ - -#if HAVE_CONFIG_H_ -# include "config.h" -#endif +#ifndef M3AP_COMMON_H_ +#define M3AP_COMMON_H_ #include "M3AP_ProtocolIE-Field.h" #include "M3AP_M3AP-PDU.h" @@ -35,8 +33,6 @@ #include "M3AP_asn_constant.h" #include "intertask_interface.h" -#ifndef M3AP_COMMON_H_ -#define M3AP_COMMON_H_ /** @defgroup _m3ap_impl_ M3AP Layer Reference Implementation * @ingroup _ref_implementation_ @@ -52,11 +48,6 @@ # define M3AP_PORT 36444 #endif -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - extern int asn1_xer_print; #if defined(ENB_MODE) diff --git a/openair3/NAS/COMMON/UTIL/nas_timer.c b/openair3/NAS/COMMON/UTIL/nas_timer.c index 8448d9a78cce62155edfc34ab35c266b5bfe6d48..b67a3bc232f8d8402c891e327658ab2a41b8a346 100644 --- a/openair3/NAS/COMMON/UTIL/nas_timer.c +++ b/openair3/NAS/COMMON/UTIL/nas_timer.c @@ -121,7 +121,7 @@ static nas_timer_database_t _nas_timer_db = { static void _nas_timer_db_init(void); static int _nas_timer_db_get_id(void); -static int _nas_timer_db_is_active(int id); +static bool _nas_timer_db_is_active(int id); static nas_timer_entry_t *_nas_timer_db_create_entry(long sec, nas_timer_callback_t cb, void *args); static void _nas_timer_db_delete_entry(int id); @@ -130,7 +130,7 @@ static void _nas_timer_db_insert_entry(int id, nas_timer_entry_t *te); static int _nas_timer_db_insert(timer_queue_t *entry); static nas_timer_entry_t *_nas_timer_db_remove_entry(int id); -static int _nas_timer_db_remove(timer_queue_t *entry); +static bool _nas_timer_db_remove(timer_queue_t *entry); /* * ----------------------------------------------------------------------------- @@ -408,12 +408,12 @@ static int _nas_timer_db_get_id(void) ** Others: _nas_timer_db ** ** ** ** Outputs: None ** - ** Return: TRUE if the timer entry is active; FALSE ** + ** Return: true if the timer entry is active; false ** ** if it is not an active timer entry. ** ** Others: None ** ** ** ***************************************************************************/ -static int _nas_timer_db_is_active(int id) +static bool _nas_timer_db_is_active(int id) { return ( (id != NAS_TIMER_INACTIVE_ID) && (_nas_timer_db.tq[id].id != NAS_TIMER_INACTIVE_ID) ); @@ -562,11 +562,11 @@ static int _nas_timer_db_insert(timer_queue_t *entry) } else { /* The new entry is the first entry of the list */ _nas_timer_db.head = entry; - return TRUE; + return true; } /* The new entry is NOT the first entry of the list */ - return FALSE; + return false; } /**************************************************************************** @@ -588,7 +588,7 @@ static int _nas_timer_db_insert(timer_queue_t *entry) ***************************************************************************/ static nas_timer_entry_t *_nas_timer_db_remove_entry(int id) { - int restart; + bool restart; /* The identifier of the timer is valid within the timer queue */ assert(_nas_timer_db.tq[id].id == id); @@ -622,7 +622,7 @@ static nas_timer_entry_t *_nas_timer_db_remove_entry(int id) return (_nas_timer_db.tq[id].entry); } -static int _nas_timer_db_remove(timer_queue_t *entry) +static bool _nas_timer_db_remove(timer_queue_t *entry) { /* Update the pointer from the previous entry */ /* prev ---> entry ---> next */ @@ -644,12 +644,12 @@ static int _nas_timer_db_remove(timer_queue_t *entry) if (_nas_timer_db.head != NULL) { /* Other timers are scheduled to expire */ - return TRUE; + return true; } } /* The entry was NOT the first entry of the list */ - return FALSE; + return false; } /* diff --git a/openair3/NAS/COMMON/UTIL/socket.c b/openair3/NAS/COMMON/UTIL/socket.c index 53a6ec8823d063bb5ec1d7d87154015af2981bd6..20c071203df0ab92a54c8707683c13d12a98aa5a 100644 --- a/openair3/NAS/COMMON/UTIL/socket.c +++ b/openair3/NAS/COMMON/UTIL/socket.c @@ -397,7 +397,7 @@ static int _socket_set_option(int sfd) * and it will simply open another socket on the same port and * continue listening. */ - optval = TRUE; + optval = true; if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) { return RETURNerror; @@ -405,12 +405,12 @@ static int _socket_set_option(int sfd) /* IPV6_V6ONLY socket option * ------------------------- - * When option is set to TRUE, the socket is restricted to sending and + * When option is set to true, the socket is restricted to sending and * receiving IPv6 packets only. - * When option is set to FALSE, the socket can be used to send and receive + * When option is set to false, the socket can be used to send and receive * packets to and from an IPv6 address or an IPv4-mapped IPv6 address. */ - optval = FALSE; + optval = false; if (setsockopt (sfd, IPPROTO_IPV6, IPV6_V6ONLY, &optval, sizeof(optval)) < 0) { return RETURNerror; diff --git a/openair3/NAS/COMMON/UTIL/stty.c b/openair3/NAS/COMMON/UTIL/stty.c index eceb0b06b139294326ef911f81de8e1aec8b68c0..fe87a63e44045ff6f50876fab2ae1c12f0c6bac2 100644 --- a/openair3/NAS/COMMON/UTIL/stty.c +++ b/openair3/NAS/COMMON/UTIL/stty.c @@ -192,7 +192,7 @@ static sttyset_t stty_params[] = { { NULL, 0, 0, 0 } }; -static int _stty_set_this(struct termios *term, const sttyset_t *p, int turnon); +static int _stty_set_this(struct termios *term, const sttyset_t *p, bool turnon); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -207,7 +207,7 @@ static int _stty_set_this(struct termios *term, const sttyset_t *p, int turnon); ** ** ** Inputs: p: The TTY parameters ** ** turnon: Indicate whether the parameter should be ** - ** turned on (TRUE) or turned off (FALSE) ** + ** turned on (true) or turned off (false) ** ** Others: None ** ** ** ** Outputs: term: The termios structure to fill ** @@ -223,7 +223,7 @@ int stty_set(int fd, const char *params) register char *s; struct termios term; register int i; - int mode; + bool mode; /* Get current tty attributes */ if ( tcgetattr(fd, &term) < 0 ) { @@ -234,10 +234,10 @@ int stty_set(int fd, const char *params) p = strtok(s," \t\n"); while (p && (rc != RETURNerror)) { - mode = 1; + mode = true; if ( *p == '-' ) { - mode = 0; + mode = false; p++; } @@ -275,7 +275,7 @@ int stty_set(int fd, const char *params) ** ** ** Inputs: p: The TTY parameters ** ** turnon: Indicate whether the parameter should be ** - ** turned on (TRUE) or turned off (FALSE) ** + ** turned on (true) or turned off (false) ** ** Others: None ** ** ** ** Outputs: term: The termios structure to fill ** @@ -283,7 +283,7 @@ int stty_set(int fd, const char *params) ** Others: None ** ** ** ***************************************************************************/ -static int _stty_set_this(struct termios *term, const sttyset_t *p, int turnon) +static int _stty_set_this(struct termios *term, const sttyset_t *p, bool turnon) { int rc = RETURNok; diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index e151fec9b43f63fa9b8d8fcb3e04faba2112a206..43c3b56aa4865bfc958a9f0f970ba0e1587a25cd 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -44,6 +44,7 @@ #include <openair3/NAS/COMMON/NR_NAS_defs.h> #include <openair1/PHY/phy_extern_nr_ue.h> #include <openair1/SIMULATION/ETH_TRANSPORT/proto.h> +#include "openair2/SDAP/nr_sdap/nr_sdap.h" uint8_t *registration_request_buf; uint32_t registration_request_len; @@ -915,7 +916,7 @@ void *nas_nrue_task(void *args_p) payload_container = pdu_buffer + offset; } offset = 0; - + uint8_t pdu_id = *(pdu_buffer+14); while(offset < payload_container_length) { // Fixme: this is not good 'type' 0x29 searching in TLV like structure // AND fix dirsty code copy hereafter of the same!!! @@ -929,9 +930,13 @@ void *nas_nrue_task(void *args_p) *(payload_container+offset+3), *(payload_container+offset+4), *(payload_container+offset+5), *(payload_container+offset+6)); nas_config(1,third_octet,fourth_octet,"oaitun_ue"); - break; } } + if (*(payload_container + offset) == 0x79) { + uint8_t qfi = *(payload_container+offset+3); + set_qfi_pduid(qfi, pdu_id); + break; + } offset++; } } diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.h b/openair3/NAS/NR_UE/nr_nas_msg_sim.h index 9655f87130f472f13a18ce1ce182bf9a6eef3b3b..abdc5b2e757642f9d8d98ff71826502c0fd53fbb 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.h +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.h @@ -80,7 +80,6 @@ typedef struct { uint8_t kgnb[32]; } ue_sa_security_key_t; - typedef enum fgs_protocol_discriminator_e { /* Protocol discriminator identifier for 5GS Mobility Management */ FGS_MOBILITY_MANAGEMENT_MESSAGE = 0x7E, diff --git a/openair3/NAS/TEST/AS_SIMULATOR/as_simulator.c b/openair3/NAS/TEST/AS_SIMULATOR/as_simulator.c index bbc37d18a3caaa3380a32c081f6afa3a0a10bd6a..387c3de3a8c07d7c8ee2d3019c5d044308b38346 100644 --- a/openair3/NAS/TEST/AS_SIMULATOR/as_simulator.c +++ b/openair3/NAS/TEST/AS_SIMULATOR/as_simulator.c @@ -120,12 +120,12 @@ static socket_id_t * _as_simulator_mme_sid = NULL; /* * UE NAS process connection manager's running indicator */ -static int _as_simulator_ue_is_running = FALSE; +static bool _as_simulator_ue_is_running = false; /* * MME NAS process connection manager's running indicator */ -static int _as_simulator_mme_is_running = FALSE; +static bool _as_simulator_mme_is_running = false; static int _set_signal_handler(int signal, void (handler)(int)); static void _signal_handler(int signal_number); @@ -307,8 +307,8 @@ static void _signal_handler(int signal_number) { printf("\nWARNING\t: %s - Signal %d received\n", __FUNCTION__, signal_number); - _as_simulator_ue_is_running = FALSE; - _as_simulator_mme_is_running = FALSE; + _as_simulator_ue_is_running = false; + _as_simulator_mme_is_running = false; } /* @@ -321,7 +321,7 @@ static void* _as_simulator_ue_mngr(void* args) int msg_id; as_message_t msg; - _as_simulator_ue_is_running = TRUE; + _as_simulator_ue_is_running = true; printf("INFO\t: %s - UE connection manager started\n", __FUNCTION__); @@ -388,7 +388,7 @@ static void* _as_simulator_ue_mngr(void* args) } /* Close the connection to the network sublayer */ - _as_simulator_ue_is_running = FALSE; + _as_simulator_ue_is_running = false; printf("ERROR\t: The UE connection manager exited\n"); return (NULL); } @@ -403,7 +403,7 @@ static void* _as_simulator_mme_mngr(void* args) int msg_id; as_message_t msg; - _as_simulator_mme_is_running = TRUE; + _as_simulator_mme_is_running = true; printf("INFO\t: %s - MME connection manager started\n", __FUNCTION__); @@ -469,7 +469,7 @@ static void* _as_simulator_mme_mngr(void* args) } /* Close the connection to the network sublayer */ - _as_simulator_mme_is_running = FALSE; + _as_simulator_mme_is_running = false; printf("ERROR\t: %s - The MME connection manager exited\n", __FUNCTION__); return (NULL); } diff --git a/openair3/NAS/TEST/NETWORK/network_simulator.c b/openair3/NAS/TEST/NETWORK/network_simulator.c index 461f701f95181d08a1c8cd2cb4a6a6de7dc33f8e..492a709463f348f0ad72b2308dbe3539dfc02fe6 100644 --- a/openair3/NAS/TEST/NETWORK/network_simulator.c +++ b/openair3/NAS/TEST/NETWORK/network_simulator.c @@ -208,7 +208,7 @@ static const OctetString* _network_simulator_pdn[NETWORK_IP_MAX][2] = { static int _set_signal_handler(int signal, void (handler)(int)); static void _signal_handler(int signal_number); static int _process_message(int msgID, const as_message_t* req); -static int _assign_pdn_address(int ue_pdn_type, int is_initial, int* pdn_type, OctetString* pdn); +static int _assign_pdn_address(int ue_pdn_type, bool is_initial, int* pdn_type, OctetString* pdn); /* Functions used to process messages received from the Access Stratum */ static int _process_cell_info_req(const cell_info_req_t* req, cell_info_cnf_t* rsp); @@ -283,7 +283,7 @@ int main (int argc, const char* argv[]) /* * Network simulator main loop */ - while (TRUE) { + while (true) { as_message_t msg; /* Receive message from the NAS */ @@ -1072,11 +1072,11 @@ static int _process_pdn_connectivity_request(const pdn_connectivity_request_msg* /* Assign PDN address */ if (apn.length > 0) { request->accesspointname.accesspointnamevalue = apn; - esm_cause = _assign_pdn_address(requested_pdn_type, FALSE, &pdn_type, + esm_cause = _assign_pdn_address(requested_pdn_type, false, &pdn_type, &request->pdnaddress.pdnaddressinformation); } else { request->accesspointname.accesspointnamevalue = EURECOM_APN; - esm_cause = _assign_pdn_address(requested_pdn_type, TRUE, &pdn_type, + esm_cause = _assign_pdn_address(requested_pdn_type, true, &pdn_type, &request->pdnaddress.pdnaddressinformation); } diff --git a/openair3/NAS/TEST/USER/user_simulator.c b/openair3/NAS/TEST/USER/user_simulator.c index 1c429c3b8508c1b766d0c27a0d1289d3d2edb8a7..3050c166927f932fe7ac37b27a175786cd884174 100644 --- a/openair3/NAS/TEST/USER/user_simulator.c +++ b/openair3/NAS/TEST/USER/user_simulator.c @@ -192,7 +192,7 @@ int main (int argc, const char* argv[]) /* * User simulator main loop */ - while (TRUE) { + while (true) { char c; int len; @@ -293,7 +293,7 @@ static void _signal_handler(int signal_number) */ static void* _receive_thread(void* arg) { - while (TRUE) { + while (true) { /* Receive AT response from the NAS sublayer */ int rbytes = USER_RECV(_user_simulator_recv_buffer, USER_SIMULATOR_BUFFER_SIZE); diff --git a/openair3/NAS/UE/API/USER/at_command.c b/openair3/NAS/UE/API/USER/at_command.c index ab85b2d2fa6fe994ffe6956e79d431c9e00a4e5c..a6591c6748227301cb9b7a3c5555d1889d084e1f 100644 --- a/openair3/NAS/UE/API/USER/at_command.c +++ b/openair3/NAS/UE/API/USER/at_command.c @@ -354,7 +354,7 @@ static int ParseString(char * at_str, at_command_t* at_command) char* terminal_character_index = NULL; int num_of_chars_to_compare = -1; int handler_index; - int handler_found = FALSE; + bool handler_found = false; int check_for_carriage_return_index = 0; /* @@ -415,7 +415,7 @@ static int ParseString(char * at_str, at_command_t* at_command) if (strncasecmp(at_str, _at_command_handler[handler_index].command, num_of_chars_to_compare) != 0) continue; - handler_found = TRUE; + handler_found = true; break; } @@ -681,7 +681,7 @@ static unsigned int NumberOfParameters(const unsigned char* str) ** Others: None ** ** ** ** Outputs: None ** - ** Return: TRUE, FALSE ** + ** Return: true, false ** ** Others: None ** ** ** ***************************************************************************/ @@ -689,11 +689,11 @@ static unsigned int IsNumeric(const char* str, size_t len) { while (len-- > 0) { if (!isdigit(str[len])) { - return FALSE; + return false; } } - return TRUE; + return true; } /****************************************************************************/ @@ -719,7 +719,7 @@ static int parse_e1(const char* string, int position, at_command_t* at_command) static int parse_q0(const char* string, int position, at_command_t* at_command) { /* Result code suppression Q0 */ - at_error_code_suppression_q1 = FALSE; + at_error_code_suppression_q1 = false; at_command->id = 0; at_command->mask = AT_COMMAND_NO_PARAM; return at_command->id; @@ -728,7 +728,7 @@ static int parse_q0(const char* string, int position, at_command_t* at_command) static int parse_q1(const char* string, int position, at_command_t* at_command) { /* Result code suppression Q1 */ - at_error_code_suppression_q1 = TRUE; + at_error_code_suppression_q1 = true; at_command->id = 0; at_command->mask = AT_COMMAND_NO_PARAM; return at_command->id; @@ -738,7 +738,7 @@ static int parse_v0(const char* string, int position, at_command_t* at_command) { /* Response format V0 (numeric result code + limited header) */ at_error_format = AT_ERROR_NUMERIC; - at_response_format_v1 = FALSE; + at_response_format_v1 = false; at_command->id = 0; at_command->mask = AT_COMMAND_NO_PARAM; return at_command->id; @@ -748,7 +748,7 @@ static int parse_v1(const char* string, int position, at_command_t* at_command) { /* Response format V1 (verbose result code + full header) */ at_error_format = AT_ERROR_VERBOSE; - at_response_format_v1 = TRUE; + at_response_format_v1 = true; at_command->id = 0; at_command->mask = AT_COMMAND_NO_PARAM; return at_command->id; diff --git a/openair3/NAS/UE/API/USER/at_error.c b/openair3/NAS/UE/API/USER/at_error.c index d004c897368bc4d467954c02ac125ea0ef856985..bad7127adc4de4cd10493c24b44edf2ad793eb5c 100644 --- a/openair3/NAS/UE/API/USER/at_error.c +++ b/openair3/NAS/UE/API/USER/at_error.c @@ -55,10 +55,10 @@ extern int at_response_format_v1; /* * Result code suppression indicator (set by ATQ0 and ATQ1) * ------------------------------------------------------- - * FALSE - Result codes are transmitted to the user application - * TRUE - Result codes are suppressed and not transmitted + * false - Result codes are transmitted to the user application + * true - Result codes are suppressed and not transmitted */ -int at_error_code_suppression_q1 = FALSE; +bool at_error_code_suppression_q1 = false; /* * Verbose mode indicator (set by ATV0, ATV1 and AT+CMEE) diff --git a/openair3/NAS/UE/API/USER/at_response.c b/openair3/NAS/UE/API/USER/at_response.c index 859db90d7e0d5393045771260e30b35f968e7484..eef0385750cffd5b181f432c84002f149ea45289 100644 --- a/openair3/NAS/UE/API/USER/at_response.c +++ b/openair3/NAS/UE/API/USER/at_response.c @@ -52,10 +52,10 @@ Description Defines structure of the AT command response returned after /* * Response format indicator (set by ATV0 and ATV1) * ----------------------------------------------- - * TRUE - <CR><LF><text><CR><LF>, <CR><LF><verbose code><CR><LF> - * FALSE - <text><CR><LF>, <numeric code><CR><LF> + * true - <CR><LF><text><CR><LF>, <CR><LF><verbose code><CR><LF> + * false - <text><CR><LF>, <numeric code><CR><LF> */ -int at_response_format_v1 = TRUE; +bool at_response_format_v1 = true; /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ diff --git a/openair3/NAS/UE/EMM/Attach.c b/openair3/NAS/UE/EMM/Attach.c index 5e7a1f578b76c68803089cb52fd1cda893b7b6fa..52f7ebce4488d0d6b39455122aa3d7f2ef518961 100644 --- a/openair3/NAS/UE/EMM/Attach.c +++ b/openair3/NAS/UE/EMM/Attach.c @@ -146,7 +146,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) /* Update the emergency bearer service indicator */ if (type == EMM_ATTACH_TYPE_EMERGENCY) { - user->emm_data->is_emergency = TRUE; + user->emm_data->is_emergency = true; } /* Setup initial NAS information message to transfer */ @@ -211,7 +211,7 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) } /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, FALSE); + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, false, false); emm_as->ksi = EMM_AS_NO_KEY_AVAILABLE; if (user->emm_data->security) { @@ -230,8 +230,8 @@ int emm_proc_attach(nas_user_t *user, emm_proc_attach_type_t type) * is requested to setup a default EPS bearer */ esm_sap.primitive = ESM_PDN_CONNECTIVITY_REQ; - esm_sap.is_standalone = FALSE; - esm_sap.data.pdn_connect.is_defined = TRUE; + esm_sap.is_standalone = false; + esm_sap.data.pdn_connect.is_defined = true; esm_sap.data.pdn_connect.cid = 1; /* TODO: PDN type should be set according to the IP capability of the UE */ esm_sap.data.pdn_connect.pdn_type = NET_PDN_TYPE_IPV4; @@ -387,7 +387,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, if (n_eplmns > 0) { for (i = 0; (i < n_eplmns) && (i < EMM_DATA_EPLMN_MAX); i++) { - int is_forbidden = FALSE; + bool is_forbidden = false; if (!user->emm_data->is_emergency) { /* If the attach procedure is not for emergency bearer @@ -395,7 +395,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, * code that is already in the list of forbidden PLMNs */ for (j = 0; j < user->emm_data->fplmn.n_plmns; j++) { if (PLMNS_ARE_EQUAL(eplmn[i], user->emm_data->fplmn.plmn[j])) { - is_forbidden = TRUE; + is_forbidden = true; break; } } @@ -418,7 +418,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, * Notify ESM that a default EPS bearer has to be activated */ esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REQ; - esm_sap.is_standalone = FALSE; + esm_sap.is_standalone = false; esm_sap.recv = esm_msg_pP; rc = esm_sap_send(user, &esm_sap); @@ -445,7 +445,7 @@ int emm_proc_attach_accept(nas_user_t *user, long t3412, long t3402, long t3423, emm_sap.u.emm_as.u.data.ueid = user->ueid; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, - user->emm_data->security, FALSE, TRUE); + user->emm_data->security, false, true); /* Get the activate default EPS bearer context accept message * to be transfered within the ESM container of the attach * complete message */ @@ -546,7 +546,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e case EMM_CAUSE_EPS_NOT_ALLOWED: case EMM_CAUSE_BOTH_NOT_ALLOWED: /* Consider the USIM as invalid for EPS services */ - user->emm_data->usim_is_valid = FALSE; + user->emm_data->usim_is_valid = false; /* Delete the list of equivalent PLMNs */ user->emm_data->nvdata.eplmn.n_plmns = 0; break; @@ -682,7 +682,7 @@ int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *e if (esm_msg_pP != NULL) { esm_sap_t esm_sap; esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; - esm_sap.is_standalone = FALSE; + esm_sap.is_standalone = false; esm_sap.recv = esm_msg_pP; rc = esm_sap_send(user, &esm_sap); } @@ -731,7 +731,7 @@ int emm_proc_attach_complete(void *args) /* Set the EPS update status to EU1 UPDATED */ user->emm_data->status = EU1_UPDATED; - user->emm_data->is_attached = TRUE; + user->emm_data->is_attached = true; /* * Notify EMM that network attach complete message has been delivered @@ -747,7 +747,7 @@ int emm_proc_attach_complete(void *args) * Complete message */ esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_CNF; - esm_sap.is_standalone = FALSE; + esm_sap.is_standalone = false; rc = esm_sap_send(user, &esm_sap); } @@ -766,7 +766,7 @@ int emm_proc_attach_complete(void *args) ** The UE shall restart the attach procedure when timer ** ** T3411 expires. ** ** ** - ** Inputs: is_initial: TRUE if the NAS message that failed to be ** + ** Inputs: is_initial: true if the NAS message that failed to be ** ** transfered is an initial NAS message (ESM ** ** message embedded within an Attach Request ** ** message) ** @@ -778,7 +778,7 @@ int emm_proc_attach_complete(void *args) ** Others: T3410, T3411 ** ** ** ***************************************************************************/ -int emm_proc_attach_failure(int is_initial, void *args) +int emm_proc_attach_failure(bool is_initial, void *args) { LOG_FUNC_IN; int rc = RETURNok; @@ -804,7 +804,7 @@ int emm_proc_attach_failure(int is_initial, void *args) * to be transmitted */ esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; - esm_sap.is_standalone = FALSE; + esm_sap.is_standalone = false; esm_sap.recv = NULL; } else { /* @@ -813,7 +813,7 @@ int emm_proc_attach_failure(int is_initial, void *args) * has failed to be transmitted */ esm_sap.primitive = ESM_DEFAULT_EPS_BEARER_CONTEXT_ACTIVATE_REJ; - esm_sap.is_standalone = FALSE; + esm_sap.is_standalone = false; esm_sap.recv = NULL; } @@ -919,7 +919,7 @@ int emm_proc_attach_set_emergency(emm_data_t *emm_data) LOG_TRACE(WARNING, "EMM-PROC - UE is now attached to the network for " "emergency bearer services only"); - emm_data->is_emergency = TRUE; + emm_data->is_emergency = true; LOG_FUNC_RETURN(RETURNok); } @@ -950,7 +950,7 @@ int emm_proc_attach_set_detach(void *nas_user) "EMM-PROC - UE is now locally detached from the network"); /* Reset the network attachment indicator */ - user->emm_data->is_attached = FALSE; + user->emm_data->is_attached = false; /* * Notify that the UE is locally detached from the network */ diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index a2762d08e838461323728a9f205fef783df9395f..a3b58f89f42bf5f5cd8aca173629ba623954058f 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -129,7 +129,7 @@ static int _authentication_kasme(const OctetString *autn, ** authentication challenge data and respond with an AUTHEN- ** ** TICATION RESPONSE message to the network. ** ** ** - ** Inputs: native_ksi: TRUE if the security context is of type ** + ** Inputs: native_ksi: true if the security context is of type ** ** native (for KSIASME) ** ** ksi: The NAS ket sey identifier ** ** rand: Authentication parameter RAND ** @@ -179,14 +179,14 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, OctetString res = {AUTH_RES_SIZE, authentication_data->res}; if ((memcmp(authentication_data->rand, rand->value, AUTH_CK_SIZE) != 0) || - (authentication_data->auth_process_started == FALSE)) { + (authentication_data->auth_process_started == false)) { /* * There is no valid stored RAND in the ME or the stored RAND is * different from the new received value in the AUTHENTICATION * REQUEST message OR if this is first time UE starting the * Authentication process */ - authentication_data->auth_process_started = TRUE; + authentication_data->auth_process_started = true; OctetString auts; auts.length = 0; auts.value = (uint8_t *)malloc(AUTH_AUTS_SIZE); @@ -308,7 +308,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, emm_sap.u.emm_as.u.security.res = &res; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - user->emm_data->security, FALSE, TRUE); + user->emm_data->security, false, true); rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { @@ -398,7 +398,7 @@ int emm_proc_authentication_reject(nas_user_t *user) } /* Consider the USIM invalid */ - user->emm_data->usim_is_valid = FALSE; + user->emm_data->usim_is_valid = false; /* Stop timer T3410 */ if (emm_timers->T3410.id != NAS_TIMER_INACTIVE_ID) { @@ -652,7 +652,7 @@ static int _authentication_abnormal_cases_cde(nas_user_t *user, int emm_cause, emm_sap.u.emm_as.u.security.auts = auts; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - user->emm_data->security, FALSE, TRUE); + user->emm_data->security, false, true); rc = emm_sap_send(user, &emm_sap); if (rc != RETURNerror) { diff --git a/openair3/NAS/UE/EMM/Detach.c b/openair3/NAS/UE/EMM/Detach.c index b61bcdc14dc7e7ea1d04ff61896ca4db7137d01e..654486226e0cd00b615b5bf366e1b9bc96777aec 100644 --- a/openair3/NAS/UE/EMM/Detach.c +++ b/openair3/NAS/UE/EMM/Detach.c @@ -114,7 +114,7 @@ static int _emm_detach_abort(nas_user_t *user, emm_proc_detach_type_t type); ** Return: RETURNok, RETURNerror ** ** ** ***************************************************************************/ -int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_off) +int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, bool switch_off) { LOG_FUNC_IN; @@ -154,7 +154,7 @@ int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_of emm_as->guti = user->emm_data->guti; emm_as->ueid = user->ueid; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, FALSE, TRUE); + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, false, true); /* * Notify EMM-AS SAP that Detach Request message has to @@ -280,7 +280,7 @@ int emm_proc_detach_accept(void* args) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_detach_failure(int is_initial, void *args) +int emm_proc_detach_failure(bool is_initial, void *args) { LOG_FUNC_IN; @@ -405,8 +405,7 @@ void *emm_detach_t3421_handler(void *args) emm_as->guti = user->emm_data->guti; emm_as->ueid = user->ueid; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, - FALSE, TRUE); + emm_as_set_security_data(&emm_as->sctx, user->emm_data->security, false, true); /* * Notify EMM-AS SAP that Detach Request message has to diff --git a/openair3/NAS/UE/EMM/EmmStatusHdl.c b/openair3/NAS/UE/EMM/EmmStatusHdl.c index 367d0327f4f1c6d6984adf44651c416da839b262..9ac2fc794b91a7d9397b28ab29c0456aa8b1ac43 100644 --- a/openair3/NAS/UE/EMM/EmmStatusHdl.c +++ b/openair3/NAS/UE/EMM/EmmStatusHdl.c @@ -137,8 +137,7 @@ int emm_proc_status(nas_user_t *user, int emm_cause) emm_sap.u.emm_as.u.status.guti = user->emm_data->guti; sctx = user->emm_data->security; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_sap.u.emm_as.u.status.sctx, sctx, - FALSE, TRUE); + emm_as_set_security_data(&emm_sap.u.emm_as.u.status.sctx, sctx, false, true); rc = emm_sap_send(user, &emm_sap); diff --git a/openair3/NAS/UE/EMM/Identification.c b/openair3/NAS/UE/EMM/Identification.c index 0364c6d22f2c79797a345aa2596c61e6b67ed1a2..d4fc85a931bcb6fab0cf7b39ee1f8560e4850554 100644 --- a/openair3/NAS/UE/EMM/Identification.c +++ b/openair3/NAS/UE/EMM/Identification.c @@ -199,8 +199,7 @@ int emm_proc_identification_request(nas_user_t *user, emm_proc_identity_type_t t emm_sap.u.emm_as.u.security.ueid = user->ueid; emm_sap.u.emm_as.u.security.msgType = EMM_AS_MSG_TYPE_IDENT; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - user->emm_data->security, FALSE, TRUE); + emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, user->emm_data->security, false, true); rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/EMM/IdleMode.c b/openair3/NAS/UE/EMM/IdleMode.c index 362d5e5b4af56ec9c677d7844ce51da9c0d7e007..50a318355c534cd26fe69730d0b0d03e8c75fcdd 100644 --- a/openair3/NAS/UE/EMM/IdleMode.c +++ b/openair3/NAS/UE/EMM/IdleMode.c @@ -663,8 +663,8 @@ int emm_proc_plmn_selection(nas_user_t *user, int index) ** to camp on an acceptable cell, irrespective of its PLMN ** ** identity, so that only emergency calls can be made. ** ** ** - ** Inputs: found: TRUE if a suitable cell of the chosen ** - ** PLMN has been found; FALSE otherwise. ** + ** Inputs: found: true if a suitable cell of the chosen ** + ** PLMN has been found; false otherwise. ** ** tac: The code of the location/tracking area the ** ** chosen PLMN belongs to ** ** ci: The identifier of the cell ** @@ -685,7 +685,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, emm_plmn_list_t *emm_plmn_list = user->emm_plmn_list; user_api_id_t *user_api_id = user->user_api_id; int index = emm_plmn_list->index; - int select_next_plmn = FALSE; + bool select_next_plmn = false; LOG_TRACE(INFO, "EMM-IDLE - %s cell found for PLMN %d in %s mode", (found)? "One" : "No", index, @@ -694,7 +694,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, "Automatic/manual"); if (found) { - int is_forbidden = FALSE; + bool is_forbidden = false; /* Select the PLMN of which a suitable cell has been found */ emm_data->splmn = *emm_plmn_list->plmn[index]; @@ -721,7 +721,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, /* Check if the selected PLMN is in the forbidden list */ for (i = 0; i < emm_data->fplmn.n_plmns; i++) { if (PLMNS_ARE_EQUAL(emm_data->splmn, emm_data->fplmn.plmn[i])) { - is_forbidden = TRUE; + is_forbidden = true; break; } } @@ -730,7 +730,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, for (i = 0; i < emm_data->fplmn_gprs.n_plmns; i++) { if (PLMNS_ARE_EQUAL(emm_data->splmn, emm_data->fplmn_gprs.plmn[i])) { - is_forbidden = TRUE; + is_forbidden = true; break; } } @@ -745,7 +745,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, if (!is_forbidden) { for (i = 0; i < emm_data->ftai.n_tais; i++) { if (TAIS_ARE_EQUAL(tai, emm_data->ftai.tai[i])) { - is_forbidden = TRUE; + is_forbidden = true; break; } } @@ -754,7 +754,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, if (!is_forbidden) { for (i = 0; i < emm_data->ftai_roaming.n_tais; i++) { if (TAIS_ARE_EQUAL(tai, emm_data->ftai_roaming.tai[i])) { - is_forbidden = TRUE; + is_forbidden = true; break; } } @@ -793,7 +793,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * Try to select the next PLMN in the ordered list of available PLMNs */ index += 1; - select_next_plmn = TRUE; + select_next_plmn = true; /* Bypass the previously selected PLMN */ if (index == emm_plmn_list->splmn) { @@ -809,7 +809,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, * registered or equivalent PLMNs is ongoing */ index += 1; - select_next_plmn = TRUE; + select_next_plmn = true; } else if (emm_data->plmn_mode == EMM_DATA_PLMN_MANUAL) { @@ -830,7 +830,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, */ emm_data->plmn_mode = EMM_DATA_PLMN_AUTO; index = emm_plmn_list->hplmn; - select_next_plmn = TRUE; + select_next_plmn = true; } /* @@ -851,7 +851,7 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, } else { /* No suitable cell of any PLMN within the ordered list * of available PLMNs has been found */ - select_next_plmn = FALSE; + select_next_plmn = false; emm_sap.primitive = EMMREG_NO_CELL; } } @@ -892,11 +892,11 @@ int emm_proc_plmn_selection_end(nas_user_t *user, int found, tac_t tac, ci_t ci, if (emm_plmn_list->splmn == emm_plmn_list->rplmn) { /* The selected PLMN is the registered PLMN */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is the registered PLMN"); - emm_data->is_rplmn = TRUE; + emm_data->is_rplmn = true; } else if (emm_plmn_list->splmn < emm_plmn_list->hplmn) { /* The selected PLMN is in the list of equivalent PLMNs */ LOG_TRACE(INFO, "EMM-IDLE - The selected PLMN is in the list of equivalent PLMNs"); - emm_data->is_eplmn = TRUE; + emm_data->is_eplmn = true; } /* diff --git a/openair3/NAS/UE/EMM/LowerLayer.c b/openair3/NAS/UE/EMM/LowerLayer.c index 01b07fc35606b7662c6f7d545fb6c681fd1bcb9e..538ba210991e0c8d13ef2f755474ccd4f25c60ac 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.c +++ b/openair3/NAS/UE/EMM/LowerLayer.c @@ -208,7 +208,7 @@ int lowerlayer_data_ind(nas_user_t *user, const OctetString *data) LOG_FUNC_IN; esm_sap.primitive = ESM_UNITDATA_IND; - esm_sap.is_standalone = TRUE; + esm_sap.is_standalone = true; esm_sap.ueid = user->ueid; esm_sap.recv = data; @@ -250,7 +250,7 @@ int lowerlayer_data_req(nas_user_t *user, const OctetString *data) emm_sap.u.emm_as.u.data.NASmsg.length = data->length; emm_sap.u.emm_as.u.data.NASmsg.value = data->value; /* Setup EPS NAS security data */ - emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, sctx, FALSE, TRUE); + emm_as_set_security_data(&emm_sap.u.emm_as.u.data.sctx, sctx, false, true); rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); @@ -336,7 +336,7 @@ int emm_proc_lowerlayer_success(lowerlayer_data_t *lowerlayer_data) ** Description: Handles EMM procedure to be executed upon receiving noti- ** ** fication that data failed to be delivered to the network. ** ** ** - ** Inputs: is_initial: TRUE if the NAS message that failed to be ** + ** Inputs: is_initial: true if the NAS message that failed to be ** ** transfered is an initial NAS message ** ** Others: None ** ** ** @@ -345,7 +345,7 @@ int emm_proc_lowerlayer_success(lowerlayer_data_t *lowerlayer_data) ** Others: None ** ** ** ***************************************************************************/ -int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, int is_initial) +int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, bool is_initial) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/EMM/LowerLayer.h b/openair3/NAS/UE/EMM/LowerLayer.h index 0d8eefc7f3830170be3625e420df6526e39e1db2..ed60e379bc7f7be42df25efb92ad66505ef15400 100644 --- a/openair3/NAS/UE/EMM/LowerLayer.h +++ b/openair3/NAS/UE/EMM/LowerLayer.h @@ -72,7 +72,7 @@ int emm_proc_lowerlayer_initialize(lowerlayer_data_t *lowerlayer_data, lowerlaye lowerlayer_release_callback_t release, void *args); int emm_proc_lowerlayer_success(lowerlayer_data_t *lowerlayer_data); -int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, int is_initial); +int emm_proc_lowerlayer_failure(lowerlayer_data_t *lowerlayer_data, bool is_initial); int emm_proc_lowerlayer_release(lowerlayer_data_t *lowerlayer_data); diff --git a/openair3/NAS/UE/EMM/LowerLayer_defs.h b/openair3/NAS/UE/EMM/LowerLayer_defs.h index 6035d4ed12db9111ef0bd75e7f81a550c4e58018..1a0ae7d6564719fc1f61a95eb729b73c71759c23 100644 --- a/openair3/NAS/UE/EMM/LowerLayer_defs.h +++ b/openair3/NAS/UE/EMM/LowerLayer_defs.h @@ -11,7 +11,7 @@ typedef int (*lowerlayer_success_callback_t)(void *); * Type of EMM procedure callback function executed when data are not * delivered to the network because a lower layer failure occurred */ -typedef int (*lowerlayer_failure_callback_t)(int, void *); +typedef int (*lowerlayer_failure_callback_t)(bool, void *); /* * Type of EMM procedure callback function executed when NAS signalling diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c index f58cf4b9e0928a01ab2abfe425ebad06985fc0db..3fa47094c7b2e0199e59bcb814d4ec8669775236 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredAttemptingToAttach.c @@ -120,7 +120,7 @@ int EmmDeregisteredAttemptingToAttach(nas_user_t *user, const emm_reg_t *evt) /* * Data failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, false); break; default: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c index 4310f963cd41b87cffa509c059ef3f617e595df9..c0763009b850a20160799b308eea592b6fc24218 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredLimitedService.c @@ -133,7 +133,7 @@ int EmmDeregisteredLimitedService(nas_user_t *user, const emm_reg_t *evt) /* * Initial NAS message failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, TRUE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, true); break; case _EMMREG_LOWERLAYER_RELEASE: diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c index f77c2921a319070eebc069f392ed13c27afcec26..0925cb4e0f2dfa8620efdc1d413bdc7ccb2e7267 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c @@ -141,7 +141,7 @@ int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *evt) /* * Initial NAS message failed to be delivered to the network */ - rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, TRUE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, true); break; case _EMMREG_LOWERLAYER_RELEASE: diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c index fbd3e1ce63e18fe14bd96b42102553111c323ea6..2cd25f77d60d253e5287321e83d77dea2aa8b187 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegistered.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegistered.c @@ -143,7 +143,7 @@ int EmmRegistered(nas_user_t *user, const emm_reg_t *evt) /* * Data transfer message failed to be delivered */ - rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, false); break; case _EMMREG_LOWERLAYER_RELEASE: diff --git a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c index 36929fc4d7feb47b125b90d7ac92891812416327..a770e08bab2be3d82cff3f7714ccf6a22bacf7d6 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c +++ b/openair3/NAS/UE/EMM/SAP/EmmRegisteredInitiated.c @@ -240,7 +240,7 @@ int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *evt) * any message transfered by EMM common procedures requested * by the network. */ - rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, FALSE); + rc = emm_proc_lowerlayer_failure(user->lowerlayer_data, false); break; case _EMMREG_LOWERLAYER_RELEASE: diff --git a/openair3/NAS/UE/EMM/SAP/emm_as.c b/openair3/NAS/UE/EMM/SAP/emm_as.c index ea4eefadeba8ffecb1097686de6e984d5f48889f..de6dee4a5e18e741a24a2a15e1b07b517a679649 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_as.c +++ b/openair3/NAS/UE/EMM/SAP/emm_as.c @@ -679,7 +679,7 @@ static int _emm_as_cell_info_res(nas_user_t *user, const emm_as_cell_info_t *msg int AcT = NET_ACCESS_EUTRAN; - if (msg->found == TRUE) { + if (msg->found == true) { /* Get the first supported access technology */ while (AcT != NET_ACCESS_UNAVAILABLE) { if (msg->rat & (1 << AcT)) { @@ -1081,7 +1081,7 @@ static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg LOG_FUNC_IN; ul_info_transfer_req_t *as_msg = (ul_info_transfer_req_t *)ul_info_transfer_req_unaligned; int size = 0; - int is_encoded = FALSE; + bool is_encoded = false; LOG_TRACE(INFO, "EMMAS-SAP - Send AS data transfer request"); @@ -1114,7 +1114,7 @@ static int _emm_as_data_req(const emm_data_t *emm_data, const emm_as_data_t *msg default: /* Send other NAS messages as already encoded ESM messages */ size = msg->NASmsg.length; - is_encoded = TRUE; + is_encoded = true; break; } diff --git a/openair3/NAS/UE/EMM/SAP/emm_asDef.h b/openair3/NAS/UE/EMM/SAP/emm_asDef.h index 7bd464ec04d377841818163f6636d724c7d626d4..4f6182a2c9c38d1867786d8c55986643918a2a11 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_asDef.h +++ b/openair3/NAS/UE/EMM/SAP/emm_asDef.h @@ -150,7 +150,7 @@ typedef struct emm_as_establish_s { uint32_t ueid; /* UE lower layer identifier */ emm_as_EPS_identity_t UEid; /* UE's EPS mobile identity */ emm_as_security_data_t sctx;/* EPS NAS security context */ - int switch_off; /* TRUE if the UE is switched off */ + bool switch_off; /* true if the UE is switched off */ uint8_t type; /* Network attach/detach type */ uint8_t RRCcause; /* Connection establishment cause */ uint8_t RRCtype; /* Associated call type */ @@ -194,7 +194,7 @@ typedef struct emm_as_data_s { uint32_t ueid; /* UE lower layer identifier */ const GUTI_t *guti; /* GUTI temporary mobile identity */ emm_as_security_data_t sctx;/* EPS NAS security context */ - int switch_off; /* TRUE if the UE is switched off */ + bool switch_off; /* true if the UE is switched off */ uint8_t type; /* Network detach type */ uint8_t delivered; /* Data message delivery indicator */ #define EMM_AS_NAS_DATA_ATTACH 0x01 /* Attach complete */ diff --git a/openair3/NAS/UE/EMM/SAP/emm_esmDef.h b/openair3/NAS/UE/EMM/SAP/emm_esmDef.h index aac37b46bfb6680df0dc907fd41a5eab0a150a58..6e7065f9139211b89fa3a900ece1f6178cfe2f14 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_esmDef.h +++ b/openair3/NAS/UE/EMM/SAP/emm_esmDef.h @@ -71,9 +71,9 @@ typedef enum { * --------------------------------------------- */ typedef struct { - int is_emergency; /* Indicates whether the PDN connection is established + bool is_emergency; /* Indicates whether the PDN connection is established * for emergency bearer services only */ - int is_attached; /* Indicates whether the UE remains attached to the + bool is_attached; /* Indicates whether the UE remains attached to the * network */ } emm_esm_establish_t; diff --git a/openair3/NAS/UE/EMM/SAP/emm_regDef.h b/openair3/NAS/UE/EMM/SAP/emm_regDef.h index b66c0565ea6dfd0af0be73db21ae5c9c803bf82c..752f328375bc0d5764bf95472a60ad1192bdddd2 100644 --- a/openair3/NAS/UE/EMM/SAP/emm_regDef.h +++ b/openair3/NAS/UE/EMM/SAP/emm_regDef.h @@ -100,7 +100,7 @@ typedef struct { * ------------------------------------- */ typedef struct { - int is_emergency; /* TRUE if the UE was attempting to register to + bool is_emergency; /* true if the UE was attempting to register to * the network for emergency services only */ } emm_reg_attach_t; @@ -109,7 +109,7 @@ typedef struct { * ------------------------------------- */ typedef struct { - int switch_off; /* TRUE if the UE is switched off */ + bool switch_off; /* true if the UE is switched off */ int type; /* Network detach type */ } emm_reg_detach_t; diff --git a/openair3/NAS/UE/EMM/SecurityModeControl.c b/openair3/NAS/UE/EMM/SecurityModeControl.c index f9a02b1a7055a2e502d8fe758c16b101b474d31c..fd3332669b024581f5c659ccf79f543c9238874d 100644 --- a/openair3/NAS/UE/EMM/SecurityModeControl.c +++ b/openair3/NAS/UE/EMM/SecurityModeControl.c @@ -124,7 +124,7 @@ static void _security_release(emm_security_context_t *ctx); ** grity algorithm and ciphered with the selected NAS ciphe- ** ** ring algorithm. ** ** ** - ** Inputs: native_ksi: TRUE if the security context is of type ** + ** Inputs: native_ksi: true if the security context is of type ** ** native (for KSIASME) ** ** ksi: The NAS ket sey identifier ** ** seea: Selected EPS cyphering algorithm ** @@ -145,7 +145,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, int rc = RETURNerror; int emm_cause = EMM_CAUSE_SUCCESS; - int security_context_is_new = FALSE; + int security_context_is_new = false; security_data_t *security_data = user->security_data; LOG_TRACE(INFO, "EMM-PROC - Security mode control requested (ksi=%d)", @@ -263,7 +263,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, user->emm_data->security->ul_count.overflow = 0; user->emm_data->security->ul_count.seq_num = 0; /* Set new security context indicator */ - security_context_is_new = TRUE; + security_context_is_new = true; } } @@ -328,7 +328,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi, emm_sap.u.emm_as.u.security.emm_cause = emm_cause; /* Setup EPS NAS security data */ emm_as_set_security_data(&emm_sap.u.emm_as.u.security.sctx, - user->emm_data->security, security_context_is_new, TRUE); + user->emm_data->security, security_context_is_new, true); rc = emm_sap_send(user, &emm_sap); LOG_FUNC_RETURN (rc); diff --git a/openair3/NAS/UE/EMM/emmData.h b/openair3/NAS/UE/EMM/emmData.h index dfdfb34e77ecd90f9d36f2a6c382d56b4f636bbe..50219b788376782cc547146484fdb1623dfcf8ed 100644 --- a/openair3/NAS/UE/EMM/emmData.h +++ b/openair3/NAS/UE/EMM/emmData.h @@ -112,7 +112,7 @@ typedef struct { #define EMM_DETACH_COUNTER_MAX 5 unsigned int count; /* Counter used to limit the number of * subsequently detach attempts */ - int switch_off; /* UE switch-off indicator */ + bool switch_off; /* UE switch-off indicator */ emm_proc_detach_type_t type; /* Type of the detach procedure * currently in progress */ } emm_detach_data_t; @@ -249,8 +249,8 @@ typedef struct emm_data_s { emm_eps_update_t status; /* The current EPS update status */ emm_ecm_state_t ecm_status; /* The EPS Connection Management status */ - int is_attached; /* Network attachment indicator */ - int is_emergency; /* Emergency bearer services indicator*/ + bool is_attached; /* Network attachment indicator */ + bool is_emergency; /* Emergency bearer services indicator*/ /* Tracking Areas list the UE is registered to * Contains the list of TAIs that identify the tracking areas that diff --git a/openair3/NAS/UE/EMM/emm_main.c b/openair3/NAS/UE/EMM/emm_main.c index 329b59fae6746c312b3692b53393278952876369..74676c8b36baef3f685ba8a752a50080f7660daa 100644 --- a/openair3/NAS/UE/EMM/emm_main.c +++ b/openair3/NAS/UE/EMM/emm_main.c @@ -113,7 +113,7 @@ void _emm_attach_initialize(emm_attach_data_t *emm_attach_data) { void _emm_detach_initialize(emm_detach_data_t *emm_detach) { emm_detach->count = 0; - emm_detach->switch_off = FALSE; + emm_detach->switch_off = false; emm_detach->type = EMM_DETACH_TYPE_RESERVED; } @@ -137,7 +137,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c LOG_FUNC_IN; user->emm_data = calloc_or_fail(sizeof(emm_data_t)); /* USIM validity indicator */ - user->emm_data->usim_is_valid = FALSE; + user->emm_data->usim_is_valid = false; /* The IMEI read from the UE's non-volatile memory */ user->emm_data->imei = (imei_t *)malloc(sizeof(imei_t)); user->emm_data->imei->length = _emm_main_get_imei(user->emm_data->imei, imei); @@ -157,14 +157,14 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c user->emm_data->plmn_rat = NET_ACCESS_UNAVAILABLE; /* Selected PLMN */ memset(&user->emm_data->splmn, 0xFF, sizeof(plmn_t)); - user->emm_data->is_rplmn = FALSE; - user->emm_data->is_eplmn = FALSE; + user->emm_data->is_rplmn = false; + user->emm_data->is_eplmn = false; /* Radio Access Technology of the serving cell */ user->emm_data->rat = NET_ACCESS_UNAVAILABLE; /* Network registration status */ user->emm_data->stat = NET_REG_STATE_OFF; - user->emm_data->is_attached = FALSE; - user->emm_data->is_emergency = FALSE; + user->emm_data->is_attached = false; + user->emm_data->is_emergency = false; /* Location/Tracking area code */ user->emm_data->tac = 0; // two byte in hexadecimal format /* Identifier of the serving cell */ @@ -201,7 +201,7 @@ void emm_main_initialize(nas_user_t *user, emm_indication_callback_t cb, const c /* The USIM application is present and valid */ LOG_TRACE(INFO, "EMM-MAIN - USIM application data successfully read"); - user->emm_data->usim_is_valid = TRUE; + user->emm_data->usim_is_valid = true; /* print keys (for debugging) */ { @@ -844,12 +844,12 @@ AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data) ** Others: user->emm_data-> ** ** ** ** Outputs: None ** - ** Return: TRUE if the UE is currently attached to ** - ** the network; FALSE otherwise. ** + ** Return: true if the UE is currently attached to ** + ** the network; false otherwise. ** ** Others: None ** ** ** ***************************************************************************/ -int emm_main_is_attached(emm_data_t *emm_data) +bool emm_main_is_attached(emm_data_t *emm_data) { LOG_FUNC_IN; LOG_FUNC_RETURN (emm_data->is_attached); @@ -866,13 +866,13 @@ int emm_main_is_attached(emm_data_t *emm_data) ** Others: user->emm_data-> ** ** ** ** Outputs: None ** - ** Return: TRUE if the UE is currently attached or is ** + ** Return: true if the UE is currently attached or is ** ** attempting to attach to the network for ** - ** emergency bearer services; FALSE otherwise ** + ** emergency bearer services; false otherwise ** ** Others: None ** ** ** ***************************************************************************/ -int emm_main_is_emergency(emm_data_t *emm_data) +bool emm_main_is_emergency(emm_data_t *emm_data) { LOG_FUNC_IN; LOG_FUNC_RETURN (emm_data->is_attached && emm_data->is_emergency); @@ -967,8 +967,8 @@ static int _emm_main_get_imei(imei_t *imei, const char *imei_str) ** Others: None ** ** ** ** Outputs: None ** - ** Return: TRUE if the first IMSI is found to match ** - ** the second; FALSE otherwise. ** + ** Return: true if the first IMSI is found to match ** + ** the second; false otherwise. ** ** Others: None ** ** ** ***************************************************************************/ @@ -977,16 +977,16 @@ static int _emm_main_imsi_cmp(imsi_t *imsi1, imsi_t *imsi2) int i; if (imsi1->length != imsi2->length) { - return FALSE; + return false; } for (i = 0; i < imsi1->length; i++) { if (imsi1->u.value[i] != imsi2->u.value[i]) { - return FALSE; + return false; } } - return TRUE; + return true; } /**************************************************************************** diff --git a/openair3/NAS/UE/EMM/emm_main.h b/openair3/NAS/UE/EMM/emm_main.h index d30f778e3b7f7d2114e5d23c81da0cb393babcb2..d081024548ae4e2a4d705dd5a13e782990e5fb92 100644 --- a/openair3/NAS/UE/EMM/emm_main.h +++ b/openair3/NAS/UE/EMM/emm_main.h @@ -94,8 +94,8 @@ AcT_t emm_main_get_plmn_rat(emm_data_t *emm_data); const char *emm_main_get_registered_plmn(emm_plmn_list_t *emm_plmn_list, emm_data_t *emm_data, network_plmn_t *plmn, int format); /* User's getter for network attachment */ -int emm_main_is_attached(emm_data_t *emm_data); -int emm_main_is_emergency(emm_data_t *emm_data); +bool emm_main_is_attached(emm_data_t *emm_data); +bool emm_main_is_emergency(emm_data_t *emm_data); #endif /* __EMM_MAIN_H__*/ diff --git a/openair3/NAS/UE/EMM/emm_proc.h b/openair3/NAS/UE/EMM/emm_proc.h index 7d4024d9d63fd7a8ca228fe038db6f74e7311249..b93bb33bf16b7ebb31ed99b1d8d9b59bf5557feb 100644 --- a/openair3/NAS/UE/EMM/emm_proc.h +++ b/openair3/NAS/UE/EMM/emm_proc.h @@ -89,7 +89,7 @@ int emm_proc_attach_accept(nas_user_t *user, long T3412, long T3402, long T3423, const OctetString *esm_msg); int emm_proc_attach_reject(nas_user_t *user, int emm_cause, const OctetString *esm_msg); int emm_proc_attach_complete(void *args); -int emm_proc_attach_failure(int is_initial, void *args); +int emm_proc_attach_failure(bool is_initial, void *args); int emm_proc_attach_release(void *args); int emm_proc_attach_restart(nas_user_t *user); @@ -103,10 +103,10 @@ int emm_proc_attach_set_detach(void *user); * Detach procedure * -------------------------------------------------------------------------- */ -int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, int switch_off); +int emm_proc_detach(nas_user_t *user, emm_proc_detach_type_t type, bool switch_off); int emm_proc_detach_request(void *args); int emm_proc_detach_accept(void *args); -int emm_proc_detach_failure(int is_initial, void *args); +int emm_proc_detach_failure(bool is_initial, void *args); int emm_proc_detach_release(void *args); diff --git a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c index 21c3da3f195138e6dacbd6cba39c29b56b3c1a3c..db95dd648f7b3418d1166fb37a40ae4cc40f2273 100644 --- a/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DedicatedEpsBearerContextActivation.c @@ -131,7 +131,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int } /* Assign dedicated EPS bearer context */ - int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, FALSE); + int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, false); if (new_ebi == ESM_EBI_UNASSIGNED) { /* 3GPP TS 24.301, section 6.4.2.5, abnormal cases a and b @@ -141,7 +141,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int int old_pid, old_bid; /* Locally deactivate the existing EPS bearer context and proceed * with the requested dedicated EPS bearer context activation */ - rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, + rc = esm_proc_eps_bearer_context_deactivate(user, true, ebi, &old_pid, &old_bid); if (rc != RETURNok) { @@ -149,7 +149,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; } else { /* Assign new dedicated EPS bearer context */ - ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, FALSE); + ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, false); } } @@ -165,7 +165,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int *esm_cause = ESM_CAUSE_SYNTACTICAL_ERROR_IN_PACKET_FILTER; } else { /* Create new dedicated EPS bearer context */ - default_ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, FALSE, qos, tft); + default_ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, false, qos, tft); if (default_ebi != ESM_EBI_UNASSIGNED) { /* Dedicated EPS bearer contextx successfully created */ @@ -197,7 +197,7 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int ** Inputs: is_standalone: Not used ** ** ebi: EPS bearer identity ** ** msg: Encoded ESM message to be sent ** - ** ue_triggered: TRUE if the EPS bearer context procedure ** + ** ue_triggered: true if the EPS bearer context procedure ** ** was triggered by the UE ** ** Others: None ** ** ** @@ -206,8 +206,8 @@ int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered) +int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered) { LOG_FUNC_IN; @@ -268,8 +268,8 @@ int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standa ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered) +int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c index 7c528d75691bc7527513074ba2c03db974834a64..f61b1498226a312738b4239e06596bfce533be91 100644 --- a/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c +++ b/openair3/NAS/UE/ESM/DefaultEpsBearerContextActivation.c @@ -103,7 +103,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e "requested by the network (ebi=%d)", ebi); /* Assign default EPS bearer context */ - int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, TRUE); + int new_ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, true); if (new_ebi == ESM_EBI_UNASSIGNED) { /* 3GPP TS 24.301, section 6.4.1.5, abnormal cases a and b @@ -113,7 +113,7 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e int old_pid, old_bid; /* Locally deactivate the existing EPS bearer context and proceed * with the requested default EPS bearer context activation */ - rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, + rc = esm_proc_eps_bearer_context_deactivate(user, true, ebi, &old_pid, &old_bid); if (rc != RETURNok) { @@ -121,13 +121,13 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e *esm_cause = ESM_CAUSE_PROTOCOL_ERROR; } else { /* Assign new default EPS bearer context */ - ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, TRUE); + ebi = esm_ebr_assign(user->esm_ebr_data, ebi, pid+1, true); } } if (ebi != ESM_EBI_UNASSIGNED) { /* Create new default EPS bearer context */ - ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, TRUE, qos, NULL); + ebi = esm_ebr_context_create(esm_data, user->ueid, pid, ebi, true, qos, NULL); if (ebi != ESM_EBI_UNASSIGNED) { /* Default EPS bearer contextx successfully created */ @@ -165,9 +165,9 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e ** te message ** ** ebi: EPS bearer identity ** ** msg: Encoded ESM message to be sent ** - ** ue_triggered: TRUE if the EPS bearer context procedure ** + ** ue_triggered: true if the EPS bearer context procedure ** ** was triggered by the UE (should be always ** - ** TRUE) ** + ** true) ** ** Others: None ** ** ** ** Outputs: None ** @@ -175,8 +175,8 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered) +int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered) { LOG_FUNC_IN; @@ -245,8 +245,8 @@ int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalo ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered) +int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered) { LOG_FUNC_IN; @@ -344,7 +344,7 @@ int esm_proc_default_eps_bearer_context_failure(nas_user_t *user) "ESM-PROC - Default EPS bearer context activation failure"); /* Release the default EPS bearer context and enter state INACTIVE */ - int rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, ebi, &pid, &bid); + int rc = esm_proc_eps_bearer_context_deactivate(user, true, ebi, &pid, &bid); if (rc != RETURNerror) { /* Reset default EPS bearer context internal data */ diff --git a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c index 5adbae05c6fee7337d18522f57b6101f8969d891..742e70cd4a72f886a133db9975d9234472953adc 100644 --- a/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c +++ b/openair3/NAS/UE/ESM/EpsBearerContextDeactivation.c @@ -97,7 +97,7 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid); ** has an EPS bearer context with specified EPS bearer iden- ** ** tity activated. ** ** ** - ** Inputs: is local: TRUE if the EPS bearer context has to be ** + ** Inputs: is local: true if the EPS bearer context has to be ** ** locally released without peer-to-peer si- ** ** gnalling between the UE and the MME ** ** ebi: EPS bearer identity of the EPS bearer con- ** @@ -111,7 +111,7 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid); ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, int is_local, int ebi, +int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, bool is_local, int ebi, int *pid, int *bid) { LOG_FUNC_IN; @@ -213,7 +213,7 @@ int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, in * the PDN connection */ if (*esm_cause == ESM_CAUSE_REACTIVATION_REQUESTED) { esm_sap_t esm_sap; - int active = FALSE; + bool active = false; /* 3GPP TS 24.301, section 6.4.4.3 * The UE should re-initiate the UE requested PDN connectivity @@ -242,8 +242,8 @@ int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, in * Notify ESM to re-initiate PDN connectivity procedure */ esm_sap.primitive = ESM_PDN_CONNECTIVITY_REQ; - esm_sap.is_standalone = TRUE; - esm_sap.data.pdn_connect.is_defined = TRUE; + esm_sap.is_standalone = true; + esm_sap.data.pdn_connect.is_defined = true; esm_sap.data.pdn_connect.cid = pid + 1; rc = esm_sap_send(user, &esm_sap); } @@ -265,10 +265,10 @@ int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, in ** DEACTIVATE EPS BEARER CONTEXT ACCEPT message and entering ** ** the state BEARER CONTEXT INACTIVE. ** ** ** - ** Inputs: is_standalone: Should be always TRUE ** + ** Inputs: is_standalone: Should be always true ** ** ebi: EPS bearer identity ** ** msg: Encoded ESM message to be sent ** - ** ue_triggered: TRUE if the EPS bearer context procedure ** + ** ue_triggered: true if the EPS bearer context procedure ** ** was triggered by the UE ** ** Others: None ** ** ** @@ -277,8 +277,8 @@ int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, in ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered) +int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered) { LOG_FUNC_IN; @@ -371,7 +371,7 @@ static int _eps_bearer_release(nas_user_t *user, int ebi, int *pid, int *bid) LOG_TRACE(WARNING, "ESM-PROC - Failed to release EPS bearer context"); } else { /* Set the EPS bearer context state to INACTIVE */ - rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_INACTIVE, FALSE); + rc = esm_ebr_set_status(user_api_id, esm_ebr_data, ebi, ESM_EBR_INACTIVE, false); if (rc != RETURNok) { /* The EPS bearer context was already in INACTIVE state */ diff --git a/openair3/NAS/UE/ESM/EsmStatusHdl.c b/openair3/NAS/UE/ESM/EsmStatusHdl.c index def498a89b91ccc7d50cc6b4f6aa3d5cf7f5cebd..88f6550251f4d6413d950ed0ed943bb9998bacee 100644 --- a/openair3/NAS/UE/ESM/EsmStatusHdl.c +++ b/openair3/NAS/UE/ESM/EsmStatusHdl.c @@ -149,7 +149,7 @@ int esm_proc_status_ind( ** ** ** Description: Initiates ESM status procedure. ** ** ** - ** Inputs: is_standalone: Not used - Always TRUE ** + ** Inputs: is_standalone: Not used - Always true ** ** ueid: UE lower layer identifier ** ** ebi: Not used ** ** msg: Encoded ESM status message to be sent ** @@ -161,9 +161,9 @@ int esm_proc_status_ind( ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_status(nas_user_t *user, int is_standalone, +int esm_proc_status(nas_user_t *user, bool is_standalone, int ebi, OctetString *msg, - int ue_triggered) + bool ue_triggered) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/ESM/PdnConnectivity.c b/openair3/NAS/UE/ESM/PdnConnectivity.c index d17b5fde3c72341a94af41151acffbd4f2960c5e..a79320cccbd0d270d95bd96eba1a06d28d4eef3c 100644 --- a/openair3/NAS/UE/ESM/PdnConnectivity.c +++ b/openair3/NAS/UE/ESM/PdnConnectivity.c @@ -80,7 +80,7 @@ Description Defines the PDN connectivity ESM procedure executed by the * PDN connection handlers */ static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetString *apn, - esm_proc_pdn_type_t pdn_type, int is_emergency); + esm_proc_pdn_type_t pdn_type, bool is_emergency); static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_addr, int esm_cause); static int _pdn_connectivity_delete(esm_data_t *esm_data, int pid); @@ -121,7 +121,7 @@ static void *_pdn_connectivity_t3482_handler(void *); ** to be defined or undefined ** ** pdn_type: PDN connection type (IPv4, IPv6, IPv4v6) ** ** apn: Access Point logical Name to be used ** - ** is_emergency: TRUE if the PDN connection has to be esta- ** + ** is_emergency: true if the PDN connection has to be esta- ** ** blished for emergency bearer services ** ** Others: None ** ** ** @@ -133,7 +133,7 @@ static void *_pdn_connectivity_t3482_handler(void *); ***************************************************************************/ int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int is_to_define, esm_proc_pdn_type_t pdn_type, - const OctetString *apn, int is_emergency, + const OctetString *apn, bool is_emergency, unsigned int *pti) { LOG_FUNC_IN; @@ -270,7 +270,7 @@ int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int is_to_define, ** pti: Procedure transaction identity ** ** msg: Encoded PDN connectivity request message ** ** to be sent ** - ** sent_by_ue: Not used - Always TRUE ** + ** sent_by_ue: Not used - Always true ** ** Others: None ** ** ** ** Outputs: None ** @@ -278,8 +278,8 @@ int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int is_to_define, ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int pti, - OctetString *msg, int sent_by_ue) +int esm_proc_pdn_connectivity_request(nas_user_t *user, bool is_standalone, int pti, + OctetString *msg, bool sent_by_ue) { LOG_FUNC_IN; esm_pt_data_t *esm_pt_data = user->esm_pt_data; @@ -523,7 +523,7 @@ int esm_proc_pdn_connectivity_complete(nas_user_t *user) ** PDN connectivity procedure which is still pending in the ** ** PROCEDURE TRANSACTION INACTIVE or PENDING state. ** ** ** - ** Inputs: is_pending: TRUE if this PDN connectivity procedure ** + ** Inputs: is_pending: true if this PDN connectivity procedure ** ** transaction is in the PENDING state ** ** Others: None ** ** ** @@ -679,7 +679,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) ** Inputs: pid: Identifier of the PDN connection entry ** ** apn: Access Point Name of the PDN connection ** ** pdn_type: PDN type (IPv4, IPv6, IPv4v6) ** - ** is_emergency: TRUE if the PDN connection has to be esta- ** + ** is_emergency: true if the PDN connection has to be esta- ** ** blished for emergency bearer services ** ** ** ** Outputs: None ** @@ -688,7 +688,7 @@ static void *_pdn_connectivity_t3482_handler(void *args) ***************************************************************************/ static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetString *apn, esm_proc_pdn_type_t pdn_type, - int is_emergency) + bool is_emergency) { esm_pdn_t *pdn = NULL; @@ -720,7 +720,7 @@ static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetSt /* Set the PDN connection identifier */ esm_data->pdn[pid].pid = pid; /* Reset the PDN connection active indicator */ - esm_data->pdn[pid].is_active = FALSE; + esm_data->pdn[pid].is_active = false; /* Setup the PDN connection data */ esm_data->pdn[pid].data = pdn; } @@ -744,7 +744,7 @@ static int _pdn_connectivity_create(esm_data_t *esm_data, int pid, const OctetSt } pdn->type = pdn_type; - pdn->addr_realloc = FALSE; + pdn->addr_realloc = false; return (RETURNok); } @@ -825,7 +825,7 @@ static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetSt * the other IP version using the UE requested PDN connectivity * procedure to the same APN with a single address PDN type * (IPv4 or IPv6) other than the one already activated */ - pdn->addr_realloc = TRUE; + pdn->addr_realloc = true; } else if ( (esm_cause == ESM_CAUSE_PDN_TYPE_IPV4_ONLY_ALLOWED) || (esm_cause == ESM_CAUSE_PDN_TYPE_IPV6_ONLY_ALLOWED) ) { /* The UE requested IPv4 or IPv6 address and the network allows @@ -833,9 +833,9 @@ static int _pdn_connectivity_update(esm_data_t *esm_data, int pid, const OctetSt * The UE shall not subsequently initiate another UE requested * PDN connectivity procedure to the same APN to obtain a PDN * type different from the one allowed by the network */ - pdn->addr_realloc = FALSE; + pdn->addr_realloc = false; } else if (pdn_type != ESM_PDN_TYPE_IPV4V6) { - pdn->addr_realloc = TRUE; + pdn->addr_realloc = true; } return (RETURNok); diff --git a/openair3/NAS/UE/ESM/PdnDisconnect.c b/openair3/NAS/UE/ESM/PdnDisconnect.c index 6665126e40a007983969db1277173129929cd37d..cb7b3225bcfab82c0ea452c0d5a9dbd765c4789a 100644 --- a/openair3/NAS/UE/ESM/PdnDisconnect.c +++ b/openair3/NAS/UE/ESM/PdnDisconnect.c @@ -155,7 +155,7 @@ int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, un ** PDN DISCONNECT REQUEST message to the MME, starting timer ** ** T3492 and entering state PROCEDURE TRANSACTION PENDING. ** ** ** - ** Inputs: is_standalone: Should be always TRUE ** + ** Inputs: is_standalone: Should be always true ** ** pti: Procedure transaction identity ** ** msg: Encoded PDN disconnect request message to ** ** be sent ** @@ -167,8 +167,8 @@ int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, un ** Others: None ** ** ** ***************************************************************************/ -int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti, - OctetString *msg, int sent_by_ue) +int esm_proc_pdn_disconnect_request(nas_user_t *user, bool is_standalone, int pti, + OctetString *msg, bool sent_by_ue) { LOG_FUNC_IN; @@ -326,7 +326,7 @@ int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause) */ esm_sap_t esm_sap; esm_sap.primitive = ESM_EPS_BEARER_CONTEXT_DEACTIVATE_REQ; - esm_sap.is_standalone = TRUE; + esm_sap.is_standalone = true; esm_sap.recv = NULL; esm_sap.send.length = 0; esm_sap.data.eps_bearer_context_deactivate.ebi = ebi; @@ -444,7 +444,7 @@ static void *_pdn_disconnect_t3492_handler(void *args) */ esm_sap_t esm_sap; esm_sap.primitive = ESM_EPS_BEARER_CONTEXT_DEACTIVATE_REQ; - esm_sap.is_standalone = TRUE; + esm_sap.is_standalone = true; esm_sap.recv = NULL; esm_sap.send.length = 0; esm_sap.data.eps_bearer_context_deactivate.ebi = ebi; diff --git a/openair3/NAS/UE/ESM/SAP/esm_sap.c b/openair3/NAS/UE/ESM/SAP/esm_sap.c index e039f66a3a882c1b6304456e9698ae03f82d600e..f1663175d43cc3ba1cd9cd737b60302f0197a41e 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sap.c +++ b/openair3/NAS/UE/ESM/SAP/esm_sap.c @@ -63,9 +63,9 @@ Description Defines the ESM Service Access Points at which the EPS /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ -static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, +static int _esm_sap_recv(nas_user_t *user, int msg_type, bool is_standalone, const OctetString *req, OctetString *rsp, esm_sap_error_t *err); -static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, int pti, int ebi, +static int _esm_sap_send(nas_user_t *user, int msg_type, bool is_standalone, int pti, int ebi, const esm_sap_data_t *data, OctetString *rsp); @@ -171,7 +171,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) } /* Define new PDN context */ - rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, TRUE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, true, pdn_connect->pdn_type, &apn, pdn_connect->is_emergency, NULL); @@ -183,7 +183,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) if (pdn_connect->is_defined) { unsigned int pti; /* Assign new procedure transaction identity */ - rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, TRUE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, true, pdn_connect->pdn_type, NULL, pdn_connect->is_emergency, &pti); @@ -205,7 +205,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) if ( msg->is_standalone && pdn_connect->is_defined ) { /* Undefine the specified PDN context */ - rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, FALSE, + rc = esm_proc_pdn_connectivity(user, pdn_connect->cid, false, pdn_connect->pdn_type, NULL, pdn_connect->is_emergency, NULL); } else if (msg->recv != NULL) { @@ -214,7 +214,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) msg->recv, &msg->send, &msg->err); } else { /* The PDN connectivity procedure locally failed */ - rc = esm_proc_pdn_connectivity_failure(user, TRUE); + rc = esm_proc_pdn_connectivity_failure(user, true); } } break; @@ -230,7 +230,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) if (rc != RETURNerror) { /* Send PDN disconnect request */ - rc = _esm_sap_send(user, PDN_DISCONNECT_REQUEST, TRUE, pti, ebi, + rc = _esm_sap_send(user, PDN_DISCONNECT_REQUEST, true, pti, ebi, &msg->data, &msg->send); } } @@ -278,7 +278,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) rc = esm_proc_default_eps_bearer_context_failure(user); if (rc != RETURNerror) { - rc = esm_proc_pdn_connectivity_failure(user, FALSE); + rc = esm_proc_pdn_connectivity_failure(user, false); } break; @@ -306,7 +306,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) /* * Locally deactivate EPS bearer context */ - rc = esm_proc_eps_bearer_context_deactivate(user, TRUE, + rc = esm_proc_eps_bearer_context_deactivate(user, true, msg->data.eps_bearer_context_deactivate.ebi, &pid, &bid); } break; @@ -359,7 +359,7 @@ int esm_sap_send(nas_user_t *user, esm_sap_t *msg) ** Return: RETURNok, RETURNerror ** ** ** ***************************************************************************/ -static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, +static int _esm_sap_recv(nas_user_t *user, int msg_type, bool is_standalone, const OctetString *req, OctetString *rsp, esm_sap_error_t *err) { @@ -422,7 +422,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * was triggered network-internally */ int triggered_by_ue = (pti != PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED); /* Indicate whether the received message shall be ignored */ - int is_discarded = FALSE; + bool is_discarded = false; if (esm_cause != ESM_CAUSE_SUCCESS) { LOG_TRACE(ERROR, "ESM-SAP - Failed to decode expected ESM message " @@ -455,7 +455,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * of already accepted activate default EPS bearer context * request message */ - is_discarded = TRUE; + is_discarded = true; } } else { /* Return reject message */ @@ -493,7 +493,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * of already accepted activate dedicated EPS bearer context * request message */ - is_discarded = TRUE; + is_discarded = true; } } else { /* Return reject message */ @@ -525,7 +525,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * received with PTI reserved value, or assigned value * that does not match any PTI in use */ - is_discarded = TRUE; + is_discarded = true; } else if ( (esm_cause == ESM_CAUSE_SUCCESS) || (esm_cause == ESM_CAUSE_INVALID_EPS_BEARER_IDENTITY) ) { /* Return accept message */ @@ -541,7 +541,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * message with the EPS bearer identity set to the received * EPS bearer identity */ - is_discarded = TRUE; + is_discarded = true; } } @@ -565,7 +565,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * Ignore PDN connectivity reject message received with * reserved or unassigned EPS bearer identity value */ - is_discarded = TRUE; + is_discarded = true; } break; @@ -588,7 +588,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * Ignore PDN disconnect reject message received with * reserved or unassigned EPS bearer identity value */ - is_discarded = TRUE; + is_discarded = true; } break; @@ -629,7 +629,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, * onto the network */ esm_procedure = esm_proc_status; /* Discard received ESM message */ - is_discarded = TRUE; + is_discarded = true; } } else { /* ESM message processing succeed */ @@ -687,7 +687,7 @@ static int _esm_sap_recv(nas_user_t *user, int msg_type, int is_standalone, ** Return: RETURNok, RETURNerror ** ** ** ***************************************************************************/ -static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, +static int _esm_sap_send(nas_user_t *user, int msg_type, bool is_standalone, int pti, int ebi, const esm_sap_data_t *data, OctetString *rsp) { @@ -697,7 +697,7 @@ static int _esm_sap_send(nas_user_t *user, int msg_type, int is_standalone, int rc = RETURNok; /* Indicate whether the message is sent by the UE or the MME */ - int sent_by_ue = TRUE; + bool sent_by_ue = true; ESM_msg esm_msg; memset(&esm_msg, 0 , sizeof(ESM_msg)); diff --git a/openair3/NAS/UE/ESM/SAP/esm_sapDef.h b/openair3/NAS/UE/ESM/SAP/esm_sapDef.h index 4ff7c7e9ddccd0b5b776e356e86e8d4c90ba2b5d..2d3227ba75fbe379d46e5eea5aa177c9cd3eb84a 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_sapDef.h +++ b/openair3/NAS/UE/ESM/SAP/esm_sapDef.h @@ -109,11 +109,11 @@ typedef struct esm_activate_eps_default_bearer_context_s { */ typedef struct esm_pdn_connectivity_s { int cid; /* PDN connection local identifier */ - int is_defined; /* Indicates whether a PDN context has been defined + bool is_defined; /* Indicates whether a PDN context has been defined * for the specified APN */ int pdn_type; /* PDN address type (IPv4, IPv6, IPv4v6) */ const char *apn; /* PDN's Access Point Name */ - int is_emergency; /* Indicates whether the PDN context has been + bool is_emergency; /* Indicates whether the PDN context has been * defined to establish connection for emergency * bearer services */ } esm_pdn_connectivity_t; @@ -149,7 +149,7 @@ typedef union { typedef struct esm_sap_s { esm_primitive_t primitive; /* ESM-SAP primitive to process */ - int is_standalone; /* Indicates whether the ESM message handled + bool is_standalone; /* Indicates whether the ESM message handled * within this primitive has to be sent/received * standalone or together within an EMM related * message */ diff --git a/openair3/NAS/UE/ESM/SAP/esm_send.c b/openair3/NAS/UE/ESM/SAP/esm_send.c index 020d9d89e3c9c0188be205e4d6a30c9ad481f005..e710d745ad57c7d594c9c5b2903a91a3155efee5 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_send.c +++ b/openair3/NAS/UE/ESM/SAP/esm_send.c @@ -132,7 +132,7 @@ int esm_send_status(int pti, int ebi, esm_status_msg *msg, int esm_cause) ** Others: None ** ** ** ***************************************************************************/ -int esm_send_pdn_connectivity_request(int pti, int is_emergency, int pdn_type, +int esm_send_pdn_connectivity_request(int pti, bool is_emergency, int pdn_type, const char *apn, pdn_connectivity_request_msg *msg) { diff --git a/openair3/NAS/UE/ESM/SAP/esm_send.h b/openair3/NAS/UE/ESM/SAP/esm_send.h index f97454027ae05dde8f7ec725949c0db26a3999a0..b9bcab0f397b3054e2827be33f6e9c9127d04e13 100644 --- a/openair3/NAS/UE/ESM/SAP/esm_send.h +++ b/openair3/NAS/UE/ESM/SAP/esm_send.h @@ -40,6 +40,8 @@ Description Defines functions executed at the ESM Service Access #ifndef __ESM_SEND_H__ #define __ESM_SEND_H__ +#include <stdbool.h> + #include "EsmStatus.h" @@ -90,7 +92,7 @@ int esm_send_status(int pti, int ebi, esm_status_msg *msg, int esm_cause); * Transaction related messages * ---------------------------- */ -int esm_send_pdn_connectivity_request(int pti, int is_emergency, int pdn_type, +int esm_send_pdn_connectivity_request(int pti, bool is_emergency, int pdn_type, const char *apn, pdn_connectivity_request_msg *msg); int esm_send_pdn_disconnect_request(int pti, int ebi, pdn_disconnect_request_msg *msg); diff --git a/openair3/NAS/UE/ESM/esmData.h b/openair3/NAS/UE/ESM/esmData.h index 16f4707a3775b73b6c619078f654c6b2125098fd..525f4ec00a7d1df28ad3feffb5b601b129cfcedb 100644 --- a/openair3/NAS/UE/ESM/esmData.h +++ b/openair3/NAS/UE/ESM/esmData.h @@ -37,6 +37,7 @@ Description Defines internal private data handled by EPS Session *****************************************************************************/ #include <stdio.h> // sprintf +#include <stdbool.h> #include "networkDef.h" #include "OctetString.h" @@ -92,7 +93,7 @@ typedef enum { typedef struct esm_ebr_context_s { unsigned char ebi; /* EPS bearer identity */ esm_ebr_state status; /* EPS bearer context status */ - int is_default_ebr; /* TRUE if the bearer context is associated + bool is_default_ebr; /* bool if the bearer context is associated * to a default EPS bearer */ char cid; /* Identifier of the PDN context the EPS * bearer context has been assigned to */ @@ -137,7 +138,7 @@ typedef struct esm_bearer_s { typedef struct esm_pdn_s { unsigned int pti; /* Identity of the procedure transaction executed * to activate the PDN connection entry */ - int is_emergency; /* Emergency bearer services indicator */ + bool is_emergency; /* Emergency bearer services indicator */ OctetString apn; /* Access Point Name currently in used */ int ambr; /* Aggregate Maximum Bit Rate of this APN */ int type; /* Address PDN type (IPv4, IPv6, IPv4v6) */ @@ -147,7 +148,7 @@ typedef struct esm_pdn_s { ESM_DATA_IPV6_ADDRESS_SIZE) /* IPv4 PDN address and/or IPv6 prefix */ char ip_addr[ESM_DATA_IP_ADDRESS_SIZE+1]; - int addr_realloc; /* Indicates whether the UE is allowed to subsequently + bool addr_realloc; /* Indicates whether the UE is allowed to subsequently * request another PDN connectivity to the same APN * using an address PDN type (IPv4 or IPv6) other * than the one already activated */ @@ -175,7 +176,7 @@ typedef struct esm_data_context_s { #define ESM_DATA_PDN_MAX 4 struct { int pid; /* Identifier of the PDN connection */ - int is_active; /* TRUE/FALSE if the PDN connection is active/inactive + bool is_active; /* true/false if the PDN connection is active/inactive * or the process to activate/deactivate the PDN * connection is in progress */ esm_pdn_t *data; /* Active PDN connection data */ diff --git a/openair3/NAS/UE/ESM/esm_ebr.c b/openair3/NAS/UE/ESM/esm_ebr.c index 3a62812eca7128f6d06eba008b988b3f97c6b50b..4c6b56cec9a903ade5aa05b2d1d7a5b0ffdd9c36 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.c +++ b/openair3/NAS/UE/ESM/esm_ebr.c @@ -153,7 +153,7 @@ void esm_ebr_register_callback(esm_indication_callback_t cb) ** ebi: Identity of the new EPS bearer context ** ** cid: Identifier of the PDN context the EPS bea- ** ** rer context is associated to ** - ** default_ebr TRUE if the new bearer context is associa- ** + ** default_ebr bool if the new bearer context is associa- ** ** ted to a default EPS bearer ** ** Others: None ** ** ** @@ -163,7 +163,7 @@ void esm_ebr_register_callback(esm_indication_callback_t cb) ** the not assigned EBI (0) otherwise. ** ** ** ***************************************************************************/ -int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, int default_ebr) +int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, bool default_ebr) { esm_ebr_context_t *ebr_ctx = NULL; int i; @@ -284,7 +284,7 @@ int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, ** ** ** ebi: The identity of the EPS bearer ** ** status: The new EPS bearer context status ** - ** ue_requested: TRUE/FALSE if the modification of the EPS ** + ** ue_requested: true/false if the modification of the EPS ** ** bearer context status was requested by the ** ** UE/network ** ** Others: None ** @@ -294,7 +294,7 @@ int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, ** ** ***************************************************************************/ int esm_ebr_set_status(user_api_id_t *user_api_id, esm_ebr_data_t *esm_ebr_data, - int ebi, esm_ebr_state status, int ue_requested) + int ebi, esm_ebr_state status, bool ue_requested) { esm_ebr_context_t *ebr_ctx; esm_ebr_state old_status; @@ -385,11 +385,11 @@ esm_ebr_state esm_ebr_get_status(esm_ebr_data_t *esm_ebr_data, ** Others: None ** ** ** ** Outputs: None ** - ** Return: TRUE, FALSE ** + ** Return: true, false ** ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi) +bool esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi) { return ( (ebi != ESM_EBI_UNASSIGNED) && (ebi < ESM_EBI_MIN) ); } @@ -404,12 +404,11 @@ int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi) ** ebi: The identity of the EPS bearer ** ** ** ** Outputs: None ** - ** Return: TRUE, FALSE ** + ** Return: true, false ** ** Others: None ** ** ** ***************************************************************************/ -int esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, - int ebi) +bool esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi) { return ( (ebi == ESM_EBI_UNASSIGNED) || diff --git a/openair3/NAS/UE/ESM/esm_ebr.h b/openair3/NAS/UE/ESM/esm_ebr.h index 6de4a048a49ef7b32bc073a00a90b3df373a72fe..4447a227baa9d1630ce8cd6c57317e315963937c 100644 --- a/openair3/NAS/UE/ESM/esm_ebr.h +++ b/openair3/NAS/UE/ESM/esm_ebr.h @@ -75,15 +75,15 @@ typedef int (*esm_indication_callback_t) (user_api_id_t *user_api_id, int, netwo void esm_ebr_register_callback(esm_indication_callback_t cb); -int esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi); +bool esm_ebr_is_reserved(esm_ebr_data_t *esm_ebr_data, int ebi); esm_ebr_data_t *esm_ebr_initialize(void); -int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, int default_ebr); +int esm_ebr_assign(esm_ebr_data_t *esm_ebr_data, int ebi, int cid, bool default_ebr); int esm_ebr_release(esm_ebr_data_t *esm_ebr_data, int ebi); -int esm_ebr_set_status(user_api_id_t *user_api_id, esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, int ue_requested); +int esm_ebr_set_status(user_api_id_t *user_api_id, esm_ebr_data_t *esm_ebr_data, int ebi, esm_ebr_state status, bool ue_requested); esm_ebr_state esm_ebr_get_status(esm_ebr_data_t *esm_ebr_data, int ebi); -int esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi); +bool esm_ebr_is_not_in_use(esm_ebr_data_t *esm_ebr_data, int ebi); #endif /* __ESM_EBR_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index b801ca2ad54e788a884f0e5cb2a6ee28a3a5f263..ca69687abe5230849e6b697c6b1d554042c9f792 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -84,7 +84,7 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *, ** Inputs: ** ** pid: PDN connection identifier ** ** ebi: EPS bearer identity ** - ** is_default: TRUE if the new bearer is a default EPS ** + ** is_default: true if the new bearer is a default EPS ** ** bearer context ** ** esm_qos: EPS bearer level QoS parameters ** ** tft: Traffic flow template parameters ** @@ -98,7 +98,7 @@ static int _esm_ebr_context_check_precedence(const network_tft_t *, ***************************************************************************/ int esm_ebr_context_create( esm_data_t *esm_data, int ueid, - int pid, int ebi, int is_default, + int pid, int ebi, bool is_default, const network_qos_t *qos, const network_tft_t *tft) { int bid = 0; esm_data_context_t *esm_ctx = NULL; @@ -185,11 +185,11 @@ int esm_ebr_context_create( if (is_default) { /* Set the PDN connection activation indicator */ - esm_ctx->pdn[pid].is_active = TRUE; + esm_ctx->pdn[pid].is_active = true; /* Update the emergency bearer services indicator */ if (pdn->is_emergency) { - esm_ctx->emergency = TRUE; + esm_ctx->emergency = true; } // LG ADD TEMP @@ -383,7 +383,7 @@ int esm_ebr_context_create( ***************************************************************************/ int esm_ebr_context_release(nas_user_t *user, int ebi, int *pid, int *bid) { - int found = FALSE; + bool found = false; esm_pdn_t *pdn = NULL; esm_data_context_t *esm_ctx; esm_ebr_data_t *esm_ebr_data = user->esm_ebr_data; @@ -416,7 +416,7 @@ int esm_ebr_context_release(nas_user_t *user, } /* The EPS bearer context entry is found */ - found = TRUE; + found = true; break; } } @@ -450,7 +450,7 @@ int esm_ebr_context_release(nas_user_t *user, if (pdn->bearer[*bid] != NULL) { ebi = pdn->bearer[*bid]->ebi; - found = TRUE; + found = true; } } } @@ -503,7 +503,7 @@ int esm_ebr_context_release(nas_user_t *user, /* Set the EPS bearer context state to INACTIVE */ esm_ebr_set_status(user_api_id, esm_ebr_data, pdn->bearer[i]->ebi, - ESM_EBR_INACTIVE, TRUE); + ESM_EBR_INACTIVE, true); /* Release EPS bearer data */ esm_ebr_release(esm_ebr_data, pdn->bearer[i]->ebi); // esm_ebr_release() @@ -519,11 +519,11 @@ int esm_ebr_context_release(nas_user_t *user, } /* Reset the PDN connection activation indicator */ - esm_ctx->pdn[*pid].is_active = FALSE; + esm_ctx->pdn[*pid].is_active = false; /* Update the emergency bearer services indicator */ if (pdn->is_emergency) { - esm_ctx->emergency = FALSE; + esm_ctx->emergency = false; } } @@ -534,7 +534,7 @@ int esm_ebr_context_release(nas_user_t *user, if (esm_ctx->n_ebrs == 0) { emm_sap_t emm_sap; emm_sap.primitive = EMMESM_ESTABLISH_CNF; - emm_sap.u.emm_esm.u.establish.is_attached = FALSE; + emm_sap.u.emm_esm.u.establish.is_attached = false; (void) emm_sap_send(user, &emm_sap); } /* 3GPP TS 24.301, section 6.4.4.3, 6.4.4.6 @@ -546,8 +546,8 @@ int esm_ebr_context_release(nas_user_t *user, else if (esm_ctx->emergency && (esm_ctx->n_ebrs == 1) ) { emm_sap_t emm_sap; emm_sap.primitive = EMMESM_ESTABLISH_CNF; - emm_sap.u.emm_esm.u.establish.is_attached = TRUE; - emm_sap.u.emm_esm.u.establish.is_emergency = TRUE; + emm_sap.u.emm_esm.u.establish.is_attached = true; + emm_sap.u.emm_esm.u.establish.is_emergency = true; (void) emm_sap_send(user, &emm_sap); } diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.h b/openair3/NAS/UE/ESM/esm_ebr_context.h index d7dfb1da70f2c1a4f8861dadd1cf71e205eaa5b4..c72f3f0e8b62a834fb41e6f4771dd846490d4a34 100644 --- a/openair3/NAS/UE/ESM/esm_ebr_context.h +++ b/openair3/NAS/UE/ESM/esm_ebr_context.h @@ -66,7 +66,7 @@ typedef enum { /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int esm_ebr_context_create(esm_data_t *esm_data, int ueid, int pid, int ebi, int is_default, +int esm_ebr_context_create(esm_data_t *esm_data, int ueid, int pid, int ebi, bool is_default, const network_qos_t *qos, const network_tft_t *tft); int esm_ebr_context_release(nas_user_t *user, int ebi, int *pid, int *bid); diff --git a/openair3/NAS/UE/ESM/esm_main.c b/openair3/NAS/UE/ESM/esm_main.c index 288e7486796f68a4efa0ce3b5af16ba34cf9555f..895e463726bf7ba2447b2d0b97c854cb94186bfb 100644 --- a/openair3/NAS/UE/ESM/esm_main.c +++ b/openair3/NAS/UE/ESM/esm_main.c @@ -96,12 +96,12 @@ void esm_main_initialize(nas_user_t *user, esm_indication_callback_t cb) for (i = 0; i < ESM_DATA_PDN_MAX + 1; i++) { esm_data->pdn[i].pid = -1; - esm_data->pdn[i].is_active = FALSE; + esm_data->pdn[i].is_active = false; esm_data->pdn[i].data = NULL; } /* Emergency bearer services indicator */ - esm_data->emergency = FALSE; + esm_data->emergency = false; /* Initialize the procedure transaction identity manager */ @@ -225,12 +225,12 @@ int esm_main_get_nb_pdns(esm_data_t *esm_data) ** Inputs: None ** ** ** ** Outputs: None ** - ** Return: TRUE if a PDN connection for emergency ** + ** Return: true if a PDN connection for emergency ** ** bearer services is established ** ** Others: None ** ** ** ***************************************************************************/ -int esm_main_has_emergency(esm_data_t *esm_data) +bool esm_main_has_emergency(esm_data_t *esm_data) { LOG_FUNC_IN; @@ -245,16 +245,16 @@ int esm_main_has_emergency(esm_data_t *esm_data) ** ** ** Inputs: cid: PDN connection identifier ** ** ** - ** Outputs: state: TRUE if the current state of the PDN con- ** - ** nection is ACTIVE; FALSE otherwise. ** - ** Return: TRUE if the specified PDN connection has a ** - ** PDN context defined; FALSE if no any PDN ** + ** Outputs: state: true if the current state of the PDN con- ** + ** nection is ACTIVE; false otherwise. ** + ** Return: true if the specified PDN connection has a ** + ** PDN context defined; false if no any PDN ** ** context has been defined for the specified ** ** connection. ** ** Others: None ** ** ** ***************************************************************************/ -int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state) +bool esm_main_get_pdn_status(nas_user_t *user, int cid, bool *state) { LOG_FUNC_IN; @@ -263,14 +263,14 @@ int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state) esm_ebr_data_t *esm_ebr_data = user-> esm_ebr_data; if (pid >= ESM_DATA_PDN_MAX) { - return (FALSE); + return (false); } else if (pid != esm_data->pdn[pid].pid) { LOG_TRACE(WARNING, "ESM-MAIN - PDN connection %d is not defined", cid); - return (FALSE); + return (false); } else if (esm_data->pdn[pid].data == NULL) { LOG_TRACE(ERROR, "ESM-MAIN - PDN connection %d has not been allocated", cid); - return (FALSE); + return (false); } if (esm_data->pdn[pid].data->bearer[0] != NULL) { @@ -281,7 +281,7 @@ int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state) } /* The PDN connection has not been activated yet */ - LOG_FUNC_RETURN (TRUE); + LOG_FUNC_RETURN (true); } /**************************************************************************** @@ -301,7 +301,7 @@ int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state) ** ** ***************************************************************************/ int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, - int *is_emergency, int *is_active) + bool *is_emergency, bool *is_active) { LOG_FUNC_IN; diff --git a/openair3/NAS/UE/ESM/esm_main.h b/openair3/NAS/UE/ESM/esm_main.h index 6e6ecc0db4668b806449ecab5f2c90171adb9c48..ca8679c5b7a6cb2f90846f63b0b7db7f21b82dbf 100644 --- a/openair3/NAS/UE/ESM/esm_main.h +++ b/openair3/NAS/UE/ESM/esm_main.h @@ -69,10 +69,9 @@ void esm_main_cleanup(esm_data_t *esm_data); /* User's getter for PDN connections and EPS bearer contexts */ int esm_main_get_nb_pdns_max(esm_data_t *esm_data); int esm_main_get_nb_pdns(esm_data_t *esm_data); -int esm_main_has_emergency(esm_data_t *esm_data); -int esm_main_get_pdn_status(nas_user_t *user, int cid, int *state); -int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, int *is_emergency, - int *is_active); +bool esm_main_has_emergency(esm_data_t *esm_data); +bool esm_main_get_pdn_status(nas_user_t *user, int cid, bool *state); +int esm_main_get_pdn(esm_data_t *esm_data, int cid, int *type, const char **apn, bool *is_emergency, bool *is_active); int esm_main_get_pdn_addr(esm_data_t *esm_data, int cid, const char **ipv4addr, const char **ipv6addr); diff --git a/openair3/NAS/UE/ESM/esm_proc.h b/openair3/NAS/UE/ESM/esm_proc.h index 941cfa620db3f35fc87a2787a65238f8a29f34b1..42a925327e3bfa7a0005e3d90ff529ed4bfd5625 100644 --- a/openair3/NAS/UE/ESM/esm_proc.h +++ b/openair3/NAS/UE/ESM/esm_proc.h @@ -79,7 +79,7 @@ typedef enum { * Type of the ESM procedure callback executed when requested by the UE * or initiated by the network */ -typedef int (*esm_proc_procedure_t) (nas_user_t *user, int, int, OctetString *, int); +typedef int (*esm_proc_procedure_t) (nas_user_t *user, bool, int, OctetString *, bool); /* EPS bearer level QoS parameters */ typedef network_qos_t esm_proc_qos_t; @@ -113,8 +113,7 @@ typedef struct { * -------------------------------------------------------------------------- */ int esm_proc_status_ind(int pti, int ebi, int *esm_cause); -int esm_proc_status(nas_user_t *user, int is_standalone, int pti, OctetString *msg, - int sent_by_ue); +int esm_proc_status(nas_user_t *user, bool is_standalone, int pti, OctetString *msg, bool sent_by_ue); /* @@ -123,10 +122,10 @@ int esm_proc_status(nas_user_t *user, int is_standalone, int pti, OctetString *m * -------------------------------------------------------------------------- */ int esm_proc_pdn_connectivity(nas_user_t *user, int cid, int to_define, - esm_proc_pdn_type_t pdn_type, const OctetString *apn, int is_emergency, + esm_proc_pdn_type_t pdn_type, const OctetString *apn, bool is_emergency, unsigned int *pti); -int esm_proc_pdn_connectivity_request(nas_user_t *user, int is_standalone, int pti, - OctetString *msg, int sent_by_ue); +int esm_proc_pdn_connectivity_request(nas_user_t *user, bool is_standalone, int pti, + OctetString *msg, bool sent_by_ue); int esm_proc_pdn_connectivity_accept(nas_user_t *user, int pti, esm_proc_pdn_type_t pdn_type, const OctetString *pdn_address, const OctetString *apn, int *esm_cause); int esm_proc_pdn_connectivity_reject(nas_user_t *user, int pti, int *esm_cause); @@ -140,8 +139,8 @@ int esm_proc_pdn_connectivity_failure(nas_user_t *user, int is_pending); * -------------------------------------------------------------------------- */ int esm_proc_pdn_disconnect(esm_data_t *esm_data, int cid, unsigned int *pti, unsigned int *ebi); -int esm_proc_pdn_disconnect_request(nas_user_t *user, int is_standalone, int pti, - OctetString *msg, int sent_by_ue); +int esm_proc_pdn_disconnect_request(nas_user_t *user, bool is_standalone, int pti, + OctetString *msg, bool sent_by_ue); int esm_proc_pdn_disconnect_accept(esm_pt_data_t *esm_pt_data, int pti, int *esm_cause); int esm_proc_pdn_disconnect_reject(nas_user_t *user, int pti, int *esm_cause); @@ -157,10 +156,10 @@ int esm_proc_default_eps_bearer_context_request(nas_user_t *user, int pid, int e int esm_proc_default_eps_bearer_context_complete(default_eps_bearer_context_data_t *default_eps_bearer_context_data); int esm_proc_default_eps_bearer_context_failure(nas_user_t *user); -int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered); -int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered); +int esm_proc_default_eps_bearer_context_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered); +int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered); /* * -------------------------------------------------------------------------- @@ -171,10 +170,10 @@ int esm_proc_default_eps_bearer_context_reject(nas_user_t *user, int is_standalo int esm_proc_dedicated_eps_bearer_context_request(nas_user_t *user, int ebi, int default_ebi, const esm_proc_qos_t *qos, const esm_proc_tft_t *tft, int *esm_cause); -int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered); -int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered); +int esm_proc_dedicated_eps_bearer_context_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered); +int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered); /* * -------------------------------------------------------------------------- @@ -182,11 +181,11 @@ int esm_proc_dedicated_eps_bearer_context_reject(nas_user_t *user, int is_standa * -------------------------------------------------------------------------- */ -int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, int is_local, int ebi, int *pid, +int esm_proc_eps_bearer_context_deactivate(nas_user_t *user, bool is_local, int ebi, int *pid, int *bid); int esm_proc_eps_bearer_context_deactivate_request(nas_user_t *user, int ebi, int *esm_cause); -int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, int is_standalone, int ebi, - OctetString *msg, int ue_triggered); +int esm_proc_eps_bearer_context_deactivate_accept(nas_user_t *user, bool is_standalone, int ebi, + OctetString *msg, bool ue_triggered); #endif /* __ESM_PROC_H__*/ diff --git a/openair3/NAS/UE/ESM/esm_pt.c b/openair3/NAS/UE/ESM/esm_pt.c index f253291fd9fdcd822f2800ee0cda62d62a936a7c..d9f593fb5718918cc45f22917e32b3811c5938a4 100644 --- a/openair3/NAS/UE/ESM/esm_pt.c +++ b/openair3/NAS/UE/ESM/esm_pt.c @@ -482,11 +482,11 @@ int esm_pt_get_pending_pti(esm_pt_data_t *esm_pt_data, esm_pt_state status) ** Inputs: pti: The identity of the procedure transaction ** ** ** ** Outputs: None ** - ** Return: TRUE, FALSE ** + ** Return: true, false ** ** Others: None ** ** ** ***************************************************************************/ -int esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti) +bool esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti) { return ( (pti == ESM_PT_UNASSIGNED) || (esm_pt_data->context[pti - ESM_PTI_MIN] == NULL) || @@ -504,11 +504,11 @@ int esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti) ** Others: None ** ** ** ** Outputs: None ** - ** Return: TRUE, FALSE ** + ** Return: true, false ** ** Others: None ** ** ** ***************************************************************************/ -int esm_pt_is_reserved(int pti) +bool esm_pt_is_reserved(int pti) { return ( (pti != ESM_PT_UNASSIGNED) && (pti > ESM_PTI_MAX) ); } diff --git a/openair3/NAS/UE/ESM/esm_pt.h b/openair3/NAS/UE/ESM/esm_pt.h index 3179e0f47b7f044e105e2730cebf96859ccf7fa6..b0c62253abca39df0c3f4324c24cb5084aebc6c4 100644 --- a/openair3/NAS/UE/ESM/esm_pt.h +++ b/openair3/NAS/UE/ESM/esm_pt.h @@ -64,7 +64,7 @@ Description Defines functions used to handle ESM procedure transactions. /****************** E X P O R T E D F U N C T I O N S ******************/ /****************************************************************************/ -int esm_pt_is_reserved(int pti); +bool esm_pt_is_reserved(int pti); esm_pt_data_t *esm_pt_initialize(void); @@ -79,6 +79,6 @@ int esm_pt_set_status(esm_pt_data_t *esm_pt_data, int pti, esm_pt_state status); esm_pt_state esm_pt_get_status(esm_pt_data_t *esm_pt_data, int pti); int esm_pt_get_pending_pti(esm_pt_data_t *esm_pt_data, esm_pt_state status); -int esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti); +bool esm_pt_is_not_in_use(esm_pt_data_t *esm_pt_data, int pti); #endif /* __ESM_PT_H__*/ diff --git a/openair3/NAS/UE/UEprocess.c b/openair3/NAS/UE/UEprocess.c index 7b9a1be42242a98ac2998512af95cf85c16b9134..a3a1c9c79b6862600823b5c62fcda12bd30507ae 100644 --- a/openair3/NAS/UE/UEprocess.c +++ b/openair3/NAS/UE/UEprocess.c @@ -205,7 +205,7 @@ static void *_nas_user_mngr(void *args) LOG_FUNC_IN; pthread_setname_np( pthread_self(), "nas_user_mngr"); - int exit_loop = FALSE; + bool exit_loop = false; int *fd = (int *) args; @@ -251,7 +251,7 @@ static void *_nas_network_mngr(void *args) LOG_TRACE (INFO, "UE-MAIN - Network connection manager started (%d)", *fd); /* Network receiving loop */ - while (TRUE) { + while (true) { /* Read the network data message */ bytes = network_api_read_data (*fd); diff --git a/openair3/NAS/UE/nas_proc.c b/openair3/NAS/UE/nas_proc.c index 9350590788a738a88a11763697e34c15ed44a433..41230696a4881a9853e4f53a821a33bfcd3de6b3 100644 --- a/openair3/NAS/UE/nas_proc.c +++ b/openair3/NAS/UE/nas_proc.c @@ -64,8 +64,8 @@ Description NAS procedure call manager #define NAS_PROC_RSRP_UNKNOWN 255 -static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all); -static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all); +static int _nas_proc_activate(nas_user_t *user, int cid, bool apply_to_all); +static int _nas_proc_deactivate(nas_user_t *user, int cid, bool apply_to_all); /****************************************************************************/ /****************** E X P O R T E D F U N C T I O N S ******************/ @@ -93,7 +93,7 @@ void nas_proc_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, LOG_FUNC_IN; /* Initialize local NAS data */ - user->proc.EPS_capability_status = FALSE; + user->proc.EPS_capability_status = false; user->proc.rsrq = NAS_PROC_RSRQ_UNKNOWN; user->proc.rsrp = NAS_PROC_RSRP_UNKNOWN; @@ -129,7 +129,7 @@ void nas_proc_cleanup(nas_user_t *user) LOG_FUNC_IN; /* Detach the UE from the EPS network */ - int rc = nas_proc_detach(user, TRUE); + int rc = nas_proc_detach(user, true); if (rc != RETURNok) { LOG_TRACE(ERROR, "NAS-PROC - Failed to detach from the network"); @@ -176,7 +176,7 @@ int nas_proc_enable_s1_mode(nas_user_t *user) * Notify the EMM procedure call manager that EPS capability * of the UE is enabled */ - user->proc.EPS_capability_status = TRUE; + user->proc.EPS_capability_status = true; emm_sap.primitive = EMMREG_S1_ENABLED; rc = emm_sap_send(user, &emm_sap); @@ -209,7 +209,7 @@ int nas_proc_disable_s1_mode(nas_user_t *user) * Notify the EMM procedure call manager that EPS capability * of the UE is disabled */ - user->proc.EPS_capability_status = FALSE; + user->proc.EPS_capability_status = false; emm_sap.primitive = EMMREG_S1_DISABLED; rc = emm_sap_send(user, &emm_sap); @@ -231,7 +231,7 @@ int nas_proc_disable_s1_mode(nas_user_t *user) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_eps(nas_user_t *user, int *stat) +int nas_proc_get_eps(nas_user_t *user, bool *stat) { LOG_FUNC_IN; @@ -449,7 +449,7 @@ int nas_proc_deregister(nas_user_t *user) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format, +int nas_proc_get_reg_data(nas_user_t *user, int *mode, bool *selected, int format, network_plmn_t *oper, int *AcT) { LOG_FUNC_IN; @@ -462,12 +462,12 @@ int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format if (oper_name != NULL) { /* An operator is currently selected */ - *selected = TRUE; + *selected = true; /* Get the supported Radio Access Technology */ *AcT = emm_main_get_plmn_rat(user->emm_data); } else { /* No any operator is selected */ - *selected = FALSE; + *selected = false; *AcT = NET_ACCESS_UNAVAILABLE; } @@ -558,7 +558,7 @@ int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT) ** ** ** Description: Initiates a detach procedure ** ** ** - ** Inputs: switch_off: TRUE if the detach is due to UE switch-off ** + ** Inputs: switch_off: true if the detach is due to UE switch-off ** ** Others: None ** ** ** ** Outputs: None ** @@ -566,7 +566,7 @@ int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT) ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_detach(nas_user_t *user, int switch_off) +int nas_proc_detach(nas_user_t *user, bool switch_off) { LOG_FUNC_IN; @@ -607,7 +607,7 @@ int nas_proc_attach(nas_user_t *user) if ( !emm_main_is_attached(user->emm_data) ) { /* Initiate an Attach procedure */ emm_sap.primitive = EMMREG_ATTACH_INIT; - emm_sap.u.emm_reg.u.attach.is_emergency = FALSE; + emm_sap.u.emm_reg.u.attach.is_emergency = false; rc = emm_sap_send(user, &emm_sap); } @@ -624,16 +624,16 @@ int nas_proc_attach(nas_user_t *user) ** Others: None ** ** ** ** Outputs: None ** - ** Return: TRUE if the UE is currently attached to ** + ** Return: true if the UE is currently attached to ** ** the network ** ** Others: None ** ** ** ***************************************************************************/ -int nas_proc_get_attach_status(nas_user_t *user) +bool nas_proc_get_attach_status(nas_user_t *user) { LOG_FUNC_IN; - int is_attached = emm_main_is_attached(user->emm_data); + bool is_attached = emm_main_is_attached(user->emm_data); LOG_FUNC_RETURN (is_attached); } @@ -690,10 +690,10 @@ int nas_proc_get_pdn_status(nas_user_t *user, int *cids, int *states, int n_pdn_ /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { /* Get the status of this PDN */ - int state = FALSE; - int is_defined = esm_main_get_pdn_status(user, cid, &state); + bool state = false; + bool is_defined = esm_main_get_pdn_status(user, cid, &state); - if (is_defined != FALSE) { + if (is_defined != false) { /* This PDN has been defined */ *(cids++) = cid; *(states++) = state; @@ -734,7 +734,7 @@ int nas_proc_get_pdn_param(esm_data_t *esm_data, int *cids, int *types, const ch /* For all PDN contexts */ for (cid = 1; (cid < n_pdn+1) && (n_defined_pdn < n_pdn_max); cid++) { - int emergency, active; + bool emergency, active; /* Get PDN connection parameters */ int rc = esm_main_get_pdn(esm_data, cid, types, apns, &emergency, &active); @@ -845,8 +845,8 @@ int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int i esm_sap_t esm_sap; esm_sap.primitive = ESM_PDN_CONNECTIVITY_REQ; - esm_sap.is_standalone = TRUE; - esm_sap.data.pdn_connect.is_defined = FALSE; + esm_sap.is_standalone = true; + esm_sap.data.pdn_connect.is_defined = false; esm_sap.data.pdn_connect.cid = cid; esm_sap.data.pdn_connect.pdn_type = type; esm_sap.data.pdn_connect.apn = apn; @@ -882,8 +882,8 @@ int nas_proc_reset_pdn(nas_user_t *user, int cid) esm_sap_t esm_sap; esm_sap.primitive = ESM_PDN_CONNECTIVITY_REJ; - esm_sap.is_standalone = TRUE; - esm_sap.data.pdn_connect.is_defined = TRUE; + esm_sap.is_standalone = true; + esm_sap.data.pdn_connect.is_defined = true; esm_sap.data.pdn_connect.cid = cid; /* * Notify ESM that the specified PDN context has to be undefined @@ -916,7 +916,7 @@ int nas_proc_deactivate_pdn(nas_user_t *user, int cid) if (cid > 0) { /* Deactivate only the specified PDN context */ - rc = _nas_proc_deactivate(user, cid, FALSE); + rc = _nas_proc_deactivate(user, cid, false); } else { /* Do not deactivate the PDN connection established during initial * network attachment (identifier 1) */ @@ -924,7 +924,7 @@ int nas_proc_deactivate_pdn(nas_user_t *user, int cid) /* Deactivate all active PDN contexts */ while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(user->esm_data)+1)) { - rc = _nas_proc_deactivate(user, cid++, TRUE); + rc = _nas_proc_deactivate(user, cid++, true); } } @@ -970,13 +970,13 @@ int nas_proc_activate_pdn(nas_user_t *user, int cid) if (rc != RETURNerror) { if (cid > 0) { /* Activate only the specified PDN context */ - rc = _nas_proc_activate(user, cid, FALSE); + rc = _nas_proc_activate(user, cid, false); } else { cid = 1; /* Activate all defined PDN contexts */ while ((rc != RETURNerror) && (cid < esm_main_get_nb_pdns_max(user->esm_data)+1)) { - rc = _nas_proc_activate(user, cid++, TRUE); + rc = _nas_proc_activate(user, cid++, true); } } } @@ -1177,7 +1177,7 @@ int nas_proc_ul_transfer_cnf(nas_user_t *user) */ emm_sap.primitive = EMMAS_DATA_IND; emm_sap.u.emm_as.u.data.ueid = user->ueid; - emm_sap.u.emm_as.u.data.delivered = TRUE; + emm_sap.u.emm_as.u.data.delivered = true; emm_sap.u.emm_as.u.data.NASmsg.length = 0; rc = emm_sap_send(user, &emm_sap); @@ -1214,7 +1214,7 @@ int nas_proc_ul_transfer_rej(nas_user_t *user) */ emm_sap.primitive = EMMAS_DATA_IND; emm_sap.u.emm_as.u.data.ueid = user->ueid; - emm_sap.u.emm_as.u.data.delivered = FALSE; + emm_sap.u.emm_as.u.data.delivered = false; emm_sap.u.emm_as.u.data.NASmsg.length = 0; rc = emm_sap_send(user, &emm_sap); @@ -1251,7 +1251,7 @@ int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len) */ emm_sap.primitive = EMMAS_DATA_IND; emm_sap.u.emm_as.u.data.ueid = user->ueid; - emm_sap.u.emm_as.u.data.delivered = TRUE; + emm_sap.u.emm_as.u.data.delivered = true; emm_sap.u.emm_as.u.data.NASmsg.length = len; emm_sap.u.emm_as.u.data.NASmsg.value = (uint8_t *)data; rc = emm_sap_send(user, &emm_sap); @@ -1274,7 +1274,7 @@ int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len) ** ** ** Inputs: cid: Identifier of the PDN context used to es- ** ** tablished connectivity to specified PDN ** - ** apply_to_all: TRUE if the PDN connectivity procedure is ** + ** apply_to_all: true if the PDN connectivity procedure is ** ** initiated to establish connectivity to all ** ** defined PDNs ** ** Others: None ** @@ -1284,12 +1284,12 @@ int nas_proc_dl_transfer_ind(nas_user_t *user, const Byte_t *data, uint32_t len) ** Others: None ** ** ** ***************************************************************************/ -static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) +static int _nas_proc_activate(nas_user_t *user, int cid, bool apply_to_all) { LOG_FUNC_IN; int rc; - int active = FALSE; + bool active = false; esm_sap_t esm_sap; @@ -1332,8 +1332,8 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) * for the specified PDN */ esm_sap.primitive = ESM_PDN_CONNECTIVITY_REQ; - esm_sap.is_standalone = TRUE; - esm_sap.data.pdn_connect.is_defined = TRUE; + esm_sap.is_standalone = true; + esm_sap.data.pdn_connect.is_defined = true; esm_sap.data.pdn_connect.cid = cid; rc = esm_sap_send(user, &esm_sap); @@ -1347,7 +1347,7 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) ** Description: Initiates a PDN disconnect procedure ** ** ** ** Inputs: cid: Identifier of the PDN context ** - ** apply_to_all: TRUE if the PDN disconnect procedure is ** + ** apply_to_all: true if the PDN disconnect procedure is ** ** initiated to request disconnection from ** ** all active PDNs ** ** Others: None ** @@ -1357,15 +1357,15 @@ static int _nas_proc_activate(nas_user_t *user, int cid, int apply_to_all) ** Others: None ** ** ** ***************************************************************************/ -static int _nas_proc_deactivate(nas_user_t *user, int cid, int apply_to_all) +static int _nas_proc_deactivate(nas_user_t *user, int cid, bool apply_to_all) { LOG_FUNC_IN; int rc; int pdn_type; const char *apn; - int emergency = FALSE; - int active = FALSE; + bool emergency = false; + bool active = false; /* Get PDN context parameters */ rc = esm_main_get_pdn(user->esm_data, cid, &pdn_type, &apn, &emergency, &active); diff --git a/openair3/NAS/UE/nas_proc.h b/openair3/NAS/UE/nas_proc.h index 4e653549ae0698826f0fb69d41052a5fbbdc2429..bd88691de87f7f8176e0d1e847c9100554bf116c 100644 --- a/openair3/NAS/UE/nas_proc.h +++ b/openair3/NAS/UE/nas_proc.h @@ -74,7 +74,7 @@ void nas_proc_cleanup(nas_user_t *user); int nas_proc_enable_s1_mode(nas_user_t *user); int nas_proc_disable_s1_mode(nas_user_t *user); -int nas_proc_get_eps(nas_user_t *user, int *stat); +int nas_proc_get_eps(nas_user_t *user, bool *stat); int nas_proc_get_imsi(emm_data_t *emm_data, char *imsi_str); int nas_proc_get_msisdn(nas_user_t *user, char *msisdn_str, int *ton_npi); @@ -83,16 +83,16 @@ int nas_proc_get_signal_quality(nas_user_t *user, int *rsrq, int *rsrp); int nas_proc_register(nas_user_t *user, int mode, int format, const network_plmn_t *oper, int AcT); int nas_proc_deregister(nas_user_t *user); -int nas_proc_get_reg_data(nas_user_t *user, int *mode, int *selected, int format, +int nas_proc_get_reg_data(nas_user_t *user, int *mode, bool *selected, int format, network_plmn_t *oper, int *AcT); int nas_proc_get_oper_list(nas_user_t *user, const char **oper_list); int nas_proc_get_reg_status(nas_user_t *user, int *stat); int nas_proc_get_loc_info(nas_user_t *user, char *tac, char *ci, int *AcT); -int nas_proc_detach(nas_user_t *user, int switch_off); +int nas_proc_detach(nas_user_t *user, bool switch_off); int nas_proc_attach(nas_user_t *user); -int nas_proc_get_attach_status(nas_user_t *user); +bool nas_proc_get_attach_status(nas_user_t *user); int nas_proc_reset_pdn(nas_user_t *user, int cid); int nas_proc_set_pdn(nas_user_t *user, int cid, int type, const char *apn, int ipv4_addr, diff --git a/openair3/NAS/UE/nas_proc_defs.h b/openair3/NAS/UE/nas_proc_defs.h index 1ce2bfd929df7734eafd738df34787c388b263f6..09cf8e834e2a9113f1ebd397bd3300075ea0be01 100644 --- a/openair3/NAS/UE/nas_proc_defs.h +++ b/openair3/NAS/UE/nas_proc_defs.h @@ -1,12 +1,14 @@ #ifndef _NAS_PROC_DEFS_H #define _NAS_PROC_DEFS_H +#include <stdbool.h> + /* * Local NAS data */ typedef struct { /* EPS capibility status */ - int EPS_capability_status; + bool EPS_capability_status; /* Reference signal received quality */ int rsrq; /* Reference signal received power */ diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c index a94445349cf648597c913cc44d82583cd7300a8b..34bf6cb3ad5e923fe457c550326d63c47c10dc80 100644 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -43,10 +43,10 @@ uint16_t ue_idx_standalone = 0xFFFF; char *make_port_str_from_ueid(const char *base_port_str, int ueid); -static int nas_ue_process_events(nas_user_container_t *users, struct epoll_event *events, int nb_events) +static bool nas_ue_process_events(nas_user_container_t *users, struct epoll_event *events, int nb_events) { int event; - int exit_loop = FALSE; + bool exit_loop = false; LOG_I(NAS, "[UE] Received %d events\n", nb_events); @@ -310,7 +310,7 @@ void *nas_ue_task(void *args_p) nb_events = itti_get_events(TASK_NAS_UE, &events); if ((nb_events > 0) && (events != NULL)) { - if (nas_ue_process_events(users, events, nb_events) == TRUE) { + if (nas_ue_process_events(users, events, nb_events) == true) { LOG_E(NAS, "[UE] Received exit loop\n"); } } diff --git a/openair3/NAS/UE/nas_user.c b/openair3/NAS/UE/nas_user.c index d3467eddd518349d3f8fc527bd6c27574870daeb..56e41e4610e1fc8eedef9a774740e0388e6b7017 100644 --- a/openair3/NAS/UE/nas_user.c +++ b/openair3/NAS/UE/nas_user.c @@ -187,10 +187,10 @@ void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, ** from which data have been received ** ** Others: None ** ** ** - ** Outputs: Return: FALSE, TRUE ** + ** Outputs: Return: false, true ** ** ** ***************************************************************************/ -int nas_user_receive_and_process(nas_user_t *user, char *message) +bool nas_user_receive_and_process(nas_user_t *user, char *message) { LOG_FUNC_IN; @@ -212,13 +212,13 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) * exit from the receiving loop */ LOG_TRACE (ERROR, "UE-MAIN - " "Failed to read data from the user application layer"); - LOG_FUNC_RETURN(TRUE); + LOG_FUNC_RETURN(true); } } if (bytes == 0) { /* A signal was caught before any data were available */ - LOG_FUNC_RETURN(FALSE); + LOG_FUNC_RETURN(false); } /* Decode the user data message */ @@ -268,12 +268,12 @@ int nas_user_receive_and_process(nas_user_t *user, char *message) * exit from the receiving loop */ LOG_TRACE (ERROR, "UE-MAIN - " "Failed to send data to the user application layer"); - LOG_FUNC_RETURN(TRUE); + LOG_FUNC_RETURN(true); } } } - LOG_FUNC_RETURN(FALSE); + LOG_FUNC_RETURN(false); } /**************************************************************************** @@ -989,7 +989,7 @@ static int _nas_user_proc_cops(nas_user_t *user, const at_command_t *data) char oper_buffer[NET_FORMAT_MAX_SIZE], *oper = oper_buffer; memset(oper, 0, NET_FORMAT_MAX_SIZE); - int oper_is_selected; + bool oper_is_selected; at_response->id = data->id; at_response->type = data->type; @@ -1266,7 +1266,7 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) if (data->command.cgatt.state == AT_CGATT_ATTACHED) { ret_code = nas_proc_attach(user); } else if (data->command.cgatt.state == AT_CGATT_DETACHED) { - ret_code = nas_proc_detach(user, FALSE); + ret_code = nas_proc_detach(user, false); } if (ret_code != RETURNok) { @@ -1284,7 +1284,7 @@ static int _nas_user_proc_cgatt(nas_user_t *user, const at_command_t *data) /* * Read command returns the current EPS service state. */ - if (nas_proc_get_attach_status(user) != TRUE) { + if (nas_proc_get_attach_status(user) != true) { cgatt->state = AT_CGATT_DETACHED; } else { cgatt->state = AT_CGATT_ATTACHED; @@ -1821,7 +1821,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) int emergency = AT_CGDCONT_EBS_DEFAULT; int p_cscf = AT_CGDCONT_PCSCF_DEFAULT; int im_cn_signalling = AT_CGDCONT_IM_CM_DEFAULT; - int reset_pdn = TRUE; + bool reset_pdn = true; at_response->id = data->id; at_response->type = data->type; @@ -1870,7 +1870,7 @@ static int _nas_user_proc_cgdcont(nas_user_t *user, const at_command_t *data) break; } - reset_pdn = FALSE; + reset_pdn = false; } if (data->mask & AT_CGDCONT_APN_MASK) { diff --git a/openair3/NAS/UE/nas_user.h b/openair3/NAS/UE/nas_user.h index 1ded438ddd1c5982f42c10d3eb3121f2f1eb915a..63920540d4dd138cbe0034f02022cd7aed787f0a 100644 --- a/openair3/NAS/UE/nas_user.h +++ b/openair3/NAS/UE/nas_user.h @@ -63,7 +63,7 @@ Description NAS procedure functions triggered by the user void nas_user_initialize(nas_user_t *user, emm_indication_callback_t emm_cb, esm_indication_callback_t esm_cb, const char *version); -int nas_user_receive_and_process(nas_user_t *user, char *message); +bool nas_user_receive_and_process(nas_user_t *user, char *message); int nas_user_process_data(nas_user_t *user, const void *data); diff --git a/openair3/NGAP/ngap_common.h b/openair3/NGAP/ngap_common.h index 60f7beacd06eb9ef37d86ec705b75e627ea305b3..cfb9d63e59785b31283d852b350434c5e38693f8 100644 --- a/openair3/NGAP/ngap_common.h +++ b/openair3/NGAP/ngap_common.h @@ -33,23 +33,11 @@ */ -#if HAVE_CONFIG_H_ -# include "config.h" -#endif - #ifndef NGAP_COMMON_H_ #define NGAP_COMMON_H_ #include "common/utils/LOG/log.h" -/* replace ASN_DEBUG defined in asn_internal.h by oai tracing system - Would be cleaner to modify asn_internal.h but it seems to come - from non oai source, with BSD license, so prefer to do that here.. -*/ -#ifdef ASN_DEBUG -# undef ASN_DEBUG -#endif -#define ASN_DEBUG( x... ) LOG_I(ASN, x) #include "NGAP_ProtocolIE-Field.h" #include "NGAP_NGAP-PDU.h" @@ -102,13 +90,6 @@ # error "You are compiling ngap with the wrong version of ASN1C" #endif -#ifndef FALSE -# define FALSE (0) -#endif -#ifndef TRUE -# define TRUE (!FALSE) -#endif - #define NGAP_UE_ID_FMT "0x%06"PRIX32 extern int asn_debug; diff --git a/openair3/NGAP/ngap_gNB.c b/openair3/NGAP/ngap_gNB.c index 9d6bd7f07f31f334fcf59b5c34865d90aced2795..59e275ad537ed0631ce347817c8ed08f6d96b1cb 100644 --- a/openair3/NGAP/ngap_gNB.c +++ b/openair3/NGAP/ngap_gNB.c @@ -494,7 +494,7 @@ static int ngap_gNB_generate_ng_setup_request( ssi = (NGAP_SliceSupportItem_t *)calloc(1, sizeof(NGAP_SliceSupportItem_t)); INT8_TO_OCTET_STRING(instance_p->s_nssai[i][si].sST, &ssi->s_NSSAI.sST); - if(instance_p->s_nssai[i]->sD_flag) { + if (instance_p->s_nssai[i][si].sD_flag) { ssi->s_NSSAI.sD = calloc(1, sizeof(NGAP_SD_t)); ssi->s_NSSAI.sD->buf = calloc(3, sizeof(uint8_t)); ssi->s_NSSAI.sD->size = 3; diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index d7db2f70b435bbd7692c9be28942eba6d6254c8a..976a4220ddb2dbd08cf9cf1a677ecc702530def6 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -1369,15 +1369,6 @@ int ngap_gNB_pdusession_release_resp(instance_t instance, item->pDUSessionResourceReleaseResponseTransfer.size = 0; item->pDUSessionResourceReleaseResponseTransfer.buf = NULL; NGAP_DEBUG("pdusession_release_resp: transfer_buffer is NULL!\n"); -#ifdef ITTI_SIM - //For testing only - item->pDUSessionResourceReleaseResponseTransfer.buf = malloc(sizeof(uint8_t) * 1); - item->pDUSessionResourceReleaseResponseTransfer.size = 1; - uint8_t temp = 0; - memcpy(item->pDUSessionResourceReleaseResponseTransfer.buf, - &temp, - item->pDUSessionResourceReleaseResponseTransfer.size); -#endif } NGAP_DEBUG("pdusession_release_resp: pdusession ID %ld\n", item->pDUSessionID); ASN_SEQUENCE_ADD(&ie->value.choice.PDUSessionResourceReleasedListRelRes.list, item); diff --git a/openair3/S1AP/s1ap_common.h b/openair3/S1AP/s1ap_common.h index 3c07f92a7f5b1dd6e91ad3a833772709caf300c4..9eee0d8dff118662f58bbf85a45654b8d529fd2f 100644 --- a/openair3/S1AP/s1ap_common.h +++ b/openair3/S1AP/s1ap_common.h @@ -23,24 +23,10 @@ * @ingroup _ref_implementation_ * @{ */ - -#if HAVE_CONFIG_H_ -# include "config.h" -#endif - #ifndef S1AP_COMMON_H_ #define S1AP_COMMON_H_ - #include "common/utils/LOG/log.h" -/* replace ASN_DEBUG defined in asn_internal.h by oai tracing system - Would be cleaner to modify asn_internal.h but it seems to come - from non oai source, with BSD license, so prefer to do that here.. -*/ -#ifdef ASN_DEBUG -# undef ASN_DEBUG -#endif -#define ASN_DEBUG( x... ) LOG_I(ASN, x) #include "S1AP_ProtocolIE-Field.h" #include "S1AP_S1AP-PDU.h" @@ -61,16 +47,8 @@ # error "You are compiling s1ap with the wrong version of ASN1C" #endif -#ifndef FALSE -# define FALSE (0) -#endif -#ifndef TRUE -# define TRUE (!FALSE) -#endif - #define S1AP_UE_ID_FMT "0x%06"PRIX32 -extern int asn_debug; extern int asn1_xer_print; #if defined(ENB_MODE) diff --git a/openair3/S1AP/s1ap_eNB_trace.c b/openair3/S1AP/s1ap_eNB_trace.c index 695eeb4ef836a340f4639153ba06699172596f0b..de84682ec1aaf882446ee36720dc295b5d3e7acb 100644 --- a/openair3/S1AP/s1ap_eNB_trace.c +++ b/openair3/S1AP/s1ap_eNB_trace.c @@ -115,7 +115,7 @@ int s1ap_eNB_handle_trace_start(uint32_t assoc_id, container = &pdu->choice.initiatingMessage.value.choice.TraceStart; S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_TraceStartIEs_t, ie, container, - S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, TRUE); + S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); mme_ref_p = s1ap_eNB_get_MME(NULL, assoc_id, 0); DevAssert(mme_ref_p != NULL); if (ie != NULL) { diff --git a/openair3/SCTP/sctp_eNB_task.c b/openair3/SCTP/sctp_eNB_task.c index 06e606e36b616ecb61be147e548f4e3580dc6c65..df6dde0f9977f0882a833ecaa3aa504d8ab00472 100644 --- a/openair3/SCTP/sctp_eNB_task.c +++ b/openair3/SCTP/sctp_eNB_task.c @@ -859,7 +859,7 @@ sctp_eNB_accept_associations( struct sctp_cnx_list_elm_s *sctp_cnx) { int client_sd; - struct sockaddr saddr; + struct sockaddr_in6 saddr; socklen_t saddr_size; DevAssert(sctp_cnx != NULL); @@ -868,14 +868,14 @@ sctp_eNB_accept_associations( /* There is a new client connecting. Accept it... */ - if ((client_sd = accept(sctp_cnx->sd, &saddr, &saddr_size)) < 0) { + if ((client_sd = accept(sctp_cnx->sd, (struct sockaddr*)&saddr, &saddr_size)) < 0) { SCTP_ERROR("[%d] accept failed: %s:%d\n", sctp_cnx->sd, strerror(errno), errno); } else { struct sctp_cnx_list_elm_s *new_cnx; uint16_t port; /* This is an ipv6 socket */ - port = ((struct sockaddr_in6*)&saddr)->sin6_port; + port = saddr.sin6_port; /* Contrary to BSD, client socket does not inherit O_NONBLOCK option */ if (fcntl(client_sd, F_SETFL, O_NONBLOCK) < 0) { diff --git a/openair3/TEST/test_kdf.c b/openair3/TEST/test_kdf.c index 50a2ad347ab70d957778d86497cb953cf9e269ca..7e1b623e5e2067981b50b8547e782357a2a74dac 100644 --- a/openair3/TEST/test_kdf.c +++ b/openair3/TEST/test_kdf.c @@ -24,10 +24,6 @@ #include <unistd.h> #include <string.h> -#if HAVE_CONFIG_H -# include "config.h" -#endif - #include "test_util.h" #include "secu_defs.h" diff --git a/openair3/UTILS/conversions.h b/openair3/UTILS/conversions.h index 00b650a3025af8748abde760f2daf14d58820459..0361c34f33479331fc873378bb2d2ec8e8c4769b 100644 --- a/openair3/UTILS/conversions.h +++ b/openair3/UTILS/conversions.h @@ -70,8 +70,8 @@ /* Convert an integer on 16 bits to the given bUFFER */ #define INT16_TO_BUFFER(x, buf) \ do { \ - (buf)[0] = (x) >> 8; \ - (buf)[1] = (x); \ + (buf)[0] = ((x) >> 8) & 0xff; \ + (buf)[1] = (x) & 0xff; \ } while(0) /* Convert an array of char containing vALUE to x */ @@ -84,9 +84,9 @@ do { \ /* Convert an integer on 24 bits to the given bUFFER */ #define INT24_TO_BUFFER(x, buf) \ do { \ - (buf)[0] = (x) >> 16; \ - (buf)[1] = (x) >> 8; \ - (buf)[2] = (x); \ + (buf)[0] = ((x) >> 16) & 0xff;\ + (buf)[1] = ((x) >> 8) & 0xff; \ + (buf)[2] = (x) & 0xff; \ } while(0) /* Convert an array of char containing vALUE to x */ @@ -101,10 +101,10 @@ do { \ /* Convert an integer on 32 bits to the given bUFFER */ #define INT32_TO_BUFFER(x, buf) \ do { \ - (buf)[0] = (x) >> 24; \ - (buf)[1] = (x) >> 16; \ - (buf)[2] = (x) >> 8; \ - (buf)[3] = (x); \ + (buf)[0] = ((x) >> 24) & 0xff;\ + (buf)[1] = ((x) >> 16) & 0xff;\ + (buf)[2] = ((x) >> 8) & 0xff; \ + (buf)[3] = (x) & 0xff; \ } while(0) /* Convert an array of char containing vALUE to x */ diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 9537f9e18ae6142bb67514abda3d563f141c7d78..dc93960e5e3e7bcd606f1769c599fc8075ae0ed1 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -17,11 +17,10 @@ extern "C" { #include <openair2/COMMON/gtpv1_u_messages_types.h> #include <openair3/ocp-gtpu/gtp_itf.h> #include <openair2/LAYER2/PDCP_v10.1.0/pdcp.h> +#include <openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h> #include "openair2/SDAP/nr_sdap/nr_sdap.h" //#include <openair1/PHY/phy_extern.h> -static boolean_t is_gnb = false; - #pragma pack(1) typedef struct Gtpv1uMsgHeader { @@ -36,6 +35,22 @@ typedef struct Gtpv1uMsgHeader { teid_t teid; } __attribute__((packed)) Gtpv1uMsgHeaderT; +//TS 38.425, Figure 5.5.2.2-1 +typedef struct DlDataDeliveryStatus_flags { + uint8_t LPR:1; //Lost packet report + uint8_t FFI:1; //Final Frame Ind + uint8_t deliveredPdcpSn:1; //Highest Delivered NR PDCP SN Ind + uint8_t transmittedPdcpSn:1; //Highest Transmitted NR PDCP SN Ind + uint8_t pduType:4; //PDU type + uint8_t CR:1; //Cause Report + uint8_t deliveredReTxPdcpSn:1; //Delivered retransmitted NR PDCP SN Ind + uint8_t reTxPdcpSn:1; //Retransmitted NR PDCP SN Ind + uint8_t DRI:1; //Data Rate Indication + uint8_t deliveredPdcpSnRange:1; //Delivered NR PDCP SN Range Ind + uint8_t spare:3; + uint32_t drbBufferSize; //Desired buffer size for the data radio bearer +} __attribute__((packed)) DlDataDeliveryStatus_flagsT; + typedef struct Gtpv1uMsgHeaderOptFields { uint8_t seqNum1Oct; uint8_t seqNum2Oct; @@ -43,24 +58,29 @@ typedef struct Gtpv1uMsgHeaderOptFields { uint8_t NextExtHeaderType; } __attribute__((packed)) Gtpv1uMsgHeaderOptFieldsT; -typedef struct PDUSessionContainer { +#define DL_PDU_SESSION_INFORMATION 0 +#define UL_PDU_SESSION_INFORMATION 1 + + typedef struct PDUSessionContainer { uint8_t spare:4; uint8_t PDU_type:4; uint8_t QFI:6; - uint8_t RQI:1; - uint8_t PPP:1; + uint8_t Reflective_QoS_activation:1; + uint8_t Paging_Policy_Indicator:1; } __attribute__((packed)) PDUSessionContainerT; typedef struct Gtpv1uExtHeader { uint8_t ExtHeaderLen; PDUSessionContainerT pdusession_cntr; - //uint8_t NextExtHeaderType; + uint8_t NextExtHeaderType; }__attribute__((packed)) Gtpv1uExtHeaderT; #pragma pack() // TS 29.281, fig 5.2.1-3 #define PDU_SESSION_CONTAINER (0x85) +#define NR_RAN_CONTAINER (0x84) + // TS 29.281, 5.2.1 #define EXT_HDR_LNTH_OCTET_UNITS (4) #define NO_MORE_EXT_HDRS (0) @@ -84,16 +104,19 @@ typedef struct gtpv1u_bearer_s { tcp_udp_port_t outgoing_port; uint16_t seqNum; uint8_t npduNum; + int outgoing_qfi; } gtpv1u_bearer_t; typedef struct { map<int, gtpv1u_bearer_t> bearers; + teid_t outgoing_teid; } teidData_t; typedef struct { rnti_t rnti; ebi_t incoming_rb_id; gtpCallback callBack; + teid_t outgoing_teid; gtpCallbackSDAP callBackSDAP; int pdusession_id; } rntiData_t; @@ -137,53 +160,81 @@ instance_t legacyInstanceMapping=0; #define compatInst(a) ((a)==0 || (a)==INSTANCE_DEFAULT?legacyInstanceMapping:a) #define GTPV1U_HEADER_SIZE (8) - - -static int gtpv1uCreateAndSendMsg(int h, uint32_t peerIp, uint16_t peerPort, int msgType, teid_t teid, uint8_t *Msg,int msgLen, - bool seqNumFlag, bool npduNumFlag, bool extHdrFlag, int seqNum, int npduNum, int extHdrType) { - AssertFatal(extHdrFlag==false,"Not developped"); - int headerAdditional=0; - - if ( seqNumFlag || npduNumFlag || extHdrFlag) - headerAdditional=4; - - int fullSize=GTPV1U_HEADER_SIZE+headerAdditional+msgLen; - uint8_t buffer[fullSize]; + + #define HDR_MAX 256 // 256 is supposed to be larger than any gtp header +static int gtpv1uCreateAndSendMsg(int h, + uint32_t peerIp, + uint16_t peerPort, + int msgType, + teid_t teid, + uint8_t *Msg, + int msgLen, + bool seqNumFlag, + bool npduNumFlag, + int seqNum, + int npduNum, + int extHdrType, + uint8_t *extensionHeader_buffer, + uint8_t extensionHeader_length) { + LOG_D(GTPU, "Peer IP:%u peer port:%u outgoing teid:%u \n", peerIp, peerPort, teid); + + uint8_t buffer[msgLen+HDR_MAX]; + uint8_t *curPtr=buffer; Gtpv1uMsgHeaderT *msgHdr = (Gtpv1uMsgHeaderT *)buffer ; // N should be 0 for us (it was used only in 2G and 3G) msgHdr->PN=npduNumFlag; msgHdr->S=seqNumFlag; - msgHdr->E=extHdrFlag; + msgHdr->E = extHdrType != NO_MORE_EXT_HDRS; msgHdr->spare=0; //PT=0 is for GTP' TS 32.295 (charging) msgHdr->PT=1; msgHdr->version=1; msgHdr->msgType=msgType; - msgHdr->msgLength=htons(msgLen); + msgHdr->msgLength = htons(msgLen + extensionHeader_length); + msgHdr->teid=htonl(teid); - if ( seqNumFlag || extHdrFlag || npduNumFlag) - msgHdr->msgLength+=4; + curPtr+=sizeof(Gtpv1uMsgHeaderT); - msgHdr->teid=htonl(teid); + if (seqNumFlag || (extHdrType != NO_MORE_EXT_HDRS) || npduNumFlag) { + msgHdr->msgLength += htons(4); + *(uint16_t *)curPtr = seqNumFlag ? seqNum : 0x0000; + curPtr+=sizeof(uint16_t); + *(uint8_t *)curPtr = npduNumFlag ? npduNum : 0x00; + curPtr++; + *(uint8_t *)curPtr = extHdrType; + curPtr++; + } + + // Bug: if there is more than one extension, infinite loop on extensionHeader_buffer + while (extHdrType != NO_MORE_EXT_HDRS) { + if (extensionHeader_length > 0) { + memcpy(curPtr, extensionHeader_buffer, extensionHeader_length); + curPtr += extensionHeader_length; + LOG_D(GTPU, "Extension Header for DDD added. The length is: %d, extension header type is: %x \n", extensionHeader_length, *((uint8_t *)(buffer + 11))); + extHdrType = extensionHeader_buffer[extensionHeader_length - 1]; + LOG_D(GTPU, "Next extension header type is: %x \n", *((uint8_t *)(buffer + 11))); + } else { + LOG_W(GTPU, "Extension header type not supported, returning... \n"); + } + } - if(seqNumFlag || extHdrFlag || npduNumFlag) { - *((uint16_t *) (buffer+8)) = seqNumFlag ? htons(seqNum) : 0x0000; - *((uint8_t *) (buffer+10)) = npduNumFlag ? htons(npduNum) : 0x00; - *((uint8_t *) (buffer+11)) = extHdrFlag ? htons(extHdrType) : 0x00; + if (Msg!= NULL){ + memcpy(curPtr, Msg, msgLen); + curPtr+=msgLen; } - memcpy(buffer+GTPV1U_HEADER_SIZE+headerAdditional, Msg, msgLen); + AssertFatal(curPtr-(buffer+msgLen) < HDR_MAX, ""); // Fix me: add IPv6 support, using flag ipVersion static struct sockaddr_in to= {0}; to.sin_family = AF_INET; to.sin_port = htons(peerPort); to.sin_addr.s_addr = peerIp ; - LOG_D(GTPU,"sending packet size: %d to %s\n",fullSize, inet_ntoa(to.sin_addr) ); + LOG_D(GTPU,"sending packet size: %ld to %s\n",curPtr-buffer, inet_ntoa(to.sin_addr) ); int ret; - if ((ret=sendto(h, (void *)buffer, (size_t)fullSize, 0,(struct sockaddr *)&to, sizeof(to) )) != fullSize ) { - LOG_E(GTPU, "[SD %d] Failed to send data to " IPV4_ADDR " on port %d, buffer size %u, ret: %d, errno: %d\n", - h, IPV4_ADDR_FORMAT(peerIp), peerPort, fullSize, ret, errno); + if ((ret=sendto(h, (void *)buffer, curPtr-buffer, 0,(struct sockaddr *)&to, sizeof(to) )) != curPtr-buffer ) { + LOG_E(GTPU, "[SD %d] Failed to send data to " IPV4_ADDR " on port %d, buffer size %lu, ret: %d, errno: %d\n", + h, IPV4_ADDR_FORMAT(peerIp), peerPort, curPtr-buffer, ret, errno); return GTPNOK; } @@ -225,12 +276,8 @@ static void gtpv1uSend(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req, b // copy to release the mutex gtpv1u_bearer_t tmp=ptr2->second; pthread_mutex_unlock(&globGtp.gtp_lock); - gtpv1uCreateAndSendMsg(compatInst(instance), - tmp.outgoing_ip_addr, - tmp.outgoing_port, - GTP_GPDU, - tmp.teid_outgoing, - buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0) ; + gtpv1uCreateAndSendMsg( + compatInst(instance), tmp.outgoing_ip_addr, tmp.outgoing_port, GTP_GPDU, tmp.teid_outgoing, buffer, length, seqNumFlag, npduNumFlag, tmp.seqNum, tmp.npduNum, NO_MORE_EXT_HDRS, NULL, 0); } static void gtpv1uSend2(instance_t instance, gtpv1u_gnb_tunnel_data_req_t *req, bool seqNumFlag, bool npduNumFlag) { @@ -268,12 +315,98 @@ static void gtpv1uSend2(instance_t instance, gtpv1u_gnb_tunnel_data_req_t *req, // copy to release the mutex gtpv1u_bearer_t tmp=ptr2->second; pthread_mutex_unlock(&globGtp.gtp_lock); - gtpv1uCreateAndSendMsg(compatInst(instance), - tmp.outgoing_ip_addr, - tmp.outgoing_port, - GTP_GPDU, - tmp.teid_outgoing, - buffer, length, seqNumFlag, npduNumFlag, false, tmp.seqNum, tmp.npduNum, 0) ; + + if (tmp.outgoing_qfi != -1) { + Gtpv1uExtHeaderT ext = { 0 }; + ext.ExtHeaderLen = 1; // in quad bytes EXT_HDR_LNTH_OCTET_UNITS + ext.pdusession_cntr.spare = 0; + ext.pdusession_cntr.PDU_type = UL_PDU_SESSION_INFORMATION; + ext.pdusession_cntr.QFI = tmp.outgoing_qfi; + ext.pdusession_cntr.Reflective_QoS_activation = false; + ext.pdusession_cntr.Paging_Policy_Indicator = false; + ext.NextExtHeaderType = NO_MORE_EXT_HDRS; + + gtpv1uCreateAndSendMsg(compatInst(instance), + tmp.outgoing_ip_addr, + tmp.outgoing_port, + GTP_GPDU, + tmp.teid_outgoing, + buffer, + length, + seqNumFlag, + npduNumFlag, + tmp.seqNum, + tmp.npduNum, + PDU_SESSION_CONTAINER, + (uint8_t *)&ext, + sizeof(ext)); + } else { + gtpv1uCreateAndSendMsg( + compatInst(instance), tmp.outgoing_ip_addr, tmp.outgoing_port, GTP_GPDU, tmp.teid_outgoing, buffer, length, seqNumFlag, npduNumFlag, tmp.seqNum, tmp.npduNum, NO_MORE_EXT_HDRS, NULL, 0); + } +} + +static void fillDlDeliveryStatusReport(extensionHeader_t *extensionHeader, uint32_t RLC_buffer_availability, uint32_t NR_PDCP_PDU_SN){ + + extensionHeader->buffer[0] = (1+sizeof(DlDataDeliveryStatus_flagsT)+(NR_PDCP_PDU_SN>0?3:0)+(NR_PDCP_PDU_SN>0?1:0)+1)/4; + DlDataDeliveryStatus_flagsT DlDataDeliveryStatus; + DlDataDeliveryStatus.deliveredPdcpSn = 0; + DlDataDeliveryStatus.transmittedPdcpSn= NR_PDCP_PDU_SN>0?1:0; + DlDataDeliveryStatus.pduType = 1; + DlDataDeliveryStatus.drbBufferSize = htonl(RLC_buffer_availability); + memcpy(extensionHeader->buffer+1, &DlDataDeliveryStatus, sizeof(DlDataDeliveryStatus_flagsT)); + uint8_t offset = sizeof(DlDataDeliveryStatus_flagsT)+1; + + if(NR_PDCP_PDU_SN>0){ + extensionHeader->buffer[offset] = (NR_PDCP_PDU_SN >> 16) & 0xff; + extensionHeader->buffer[offset+1] = (NR_PDCP_PDU_SN >> 8) & 0xff; + extensionHeader->buffer[offset+2] = NR_PDCP_PDU_SN & 0xff; + LOG_D(GTPU, "Octets reporting NR_PDCP_PDU_SN, extensionHeader->buffer[offset]: %u, extensionHeader->buffer[offset+1]:%u, extensionHeader->buffer[offset+2]:%u \n", extensionHeader->buffer[offset], extensionHeader->buffer[offset+1],extensionHeader->buffer[offset+2]); + extensionHeader->buffer[offset+3] = 0x00; //Padding octet + offset = offset+3; + } + extensionHeader->buffer[offset] = 0x00; //No more extension headers + /*Total size of DDD_status PDU = size of mandatory part + + * 3 octets for highest transmitted/delivered PDCP SN + + * 1 octet for padding + 1 octet for next extension header type, + * according to TS 38.425: Fig. 5.5.2.2-1 and section 5.5.3.24*/ + extensionHeader->length = 1+sizeof(DlDataDeliveryStatus_flagsT)+ + (NR_PDCP_PDU_SN>0?3:0)+ + (NR_PDCP_PDU_SN>0?1:0)+1; +} + +static void gtpv1uSendDlDeliveryStatus(instance_t instance, gtpv1u_DU_buffer_report_req_t *req){ + rnti_t rnti=req->rnti; + int rab_id=req->pdusession_id; + pthread_mutex_lock(&globGtp.gtp_lock); + auto inst=&globGtp.instances[compatInst(instance)]; + auto ptrRnti=inst->ue2te_mapping.find(rnti); + + if ( ptrRnti==inst->ue2te_mapping.end() ) { + LOG_E(GTPU, "[%ld] GTP-U gtpv1uSend failed: while getting ue rnti %x in hashtable ue_mapping\n", instance, rnti); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } + + map<int, gtpv1u_bearer_t>::iterator ptr2=ptrRnti->second.bearers.find(rab_id); + + if ( ptr2 == ptrRnti->second.bearers.end() ) { + LOG_D(GTPU,"GTP-U instance: %ld sending a packet to a non existant RNTI:RAB: %x/%x\n", instance, rnti, rab_id); + pthread_mutex_unlock(&globGtp.gtp_lock); + return; + } + + extensionHeader_t *extensionHeader; + extensionHeader = (extensionHeader_t *) calloc(1, sizeof(extensionHeader_t)); + fillDlDeliveryStatusReport(extensionHeader, req->buffer_availability,0); + + LOG_I(GTPU,"[%ld] GTP-U sending DL Data Delivery status to RNTI:RAB:teid %x/%x/%x, oldseq %d, oldnum %d\n", + instance, rnti, rab_id,ptr2->second.teid_outgoing, ptr2->second.seqNum,ptr2->second.npduNum ); + // copy to release the mutex + gtpv1u_bearer_t tmp=ptr2->second; + pthread_mutex_unlock(&globGtp.gtp_lock); + gtpv1uCreateAndSendMsg( + compatInst(instance), tmp.outgoing_ip_addr, tmp.outgoing_port, GTP_GPDU, tmp.teid_outgoing, NULL, 0, false, false, 0, 0, NR_RAN_CONTAINER, extensionHeader->buffer, extensionHeader->length); } static void gtpv1uEndTunnel(instance_t instance, gtpv1u_enb_tunnel_data_req_t *req) { @@ -455,8 +588,16 @@ void GtpuUpdateTunnelOutgoingTeid(instance_t instance, rnti_t rnti, ebi_t bearer return; } -teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_bearer_id, teid_t outgoing_teid, - transport_layer_addr_t remoteAddr, int port, gtpCallback callBack) { +teid_t newGtpuCreateTunnel(instance_t instance, + rnti_t rnti, + int incoming_bearer_id, + int outgoing_bearer_id, + teid_t outgoing_teid, + int outgoing_qfi, + transport_layer_addr_t remoteAddr, + int port, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP) { pthread_mutex_lock(&globGtp.gtp_lock); instance=compatInst(instance); auto inst=&globGtp.instances[instance]; @@ -478,9 +619,11 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer inst->te2ue_mapping[incoming_teid].incoming_rb_id= incoming_bearer_id; + inst->te2ue_mapping[incoming_teid].outgoing_teid= outgoing_teid; + inst->te2ue_mapping[incoming_teid].callBack=callBack; - - inst->te2ue_mapping[incoming_teid].callBackSDAP = sdap_data_req; + + inst->te2ue_mapping[incoming_teid].callBackSDAP = callBackSDAP; inst->te2ue_mapping[incoming_teid].pdusession_id = (uint8_t)outgoing_bearer_id; @@ -511,6 +654,7 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer tmp->teid_incoming = incoming_teid; tmp->outgoing_port=port; tmp->teid_outgoing= outgoing_teid; + tmp->outgoing_qfi=outgoing_qfi; pthread_mutex_unlock(&globGtp.gtp_lock); char ip4[INET_ADDRSTRLEN]; char ip6[INET6_ADDRSTRLEN]; @@ -539,12 +683,16 @@ int gtpv1u_create_s1u_tunnel(instance_t instance, "From legacy code not clear, seems impossible (bearer=%d)\n", create_tunnel_req->eps_bearer_id[i]); int incoming_rb_id=create_tunnel_req->eps_bearer_id[i]-4; - teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti, - incoming_rb_id, - create_tunnel_req->eps_bearer_id[i], - create_tunnel_req->sgw_S1u_teid[i], - create_tunnel_req->sgw_addr[i], dstport, - pdcp_data_req); + teid_t teid = newGtpuCreateTunnel(compatInst(instance), + create_tunnel_req->rnti, + incoming_rb_id, + create_tunnel_req->eps_bearer_id[i], + create_tunnel_req->sgw_S1u_teid[i], + -1, // no pdu session in 4G + create_tunnel_req->sgw_addr[i], + dstport, + pdcp_data_req, + NULL); create_tunnel_resp->status=0; create_tunnel_resp->rnti=create_tunnel_req->rnti; create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels; @@ -601,15 +749,18 @@ int gtpv1u_create_ngu_tunnel( const instance_t instance, create_tunnel_req->rnti, create_tunnel_req->num_tunnels, create_tunnel_req->outgoing_teid[0]); - tcp_udp_port_t dstport=globGtp.instances[compatInst(instance)].get_dstport(); - is_gnb = true; + tcp_udp_port_t dstport = globGtp.instances[compatInst(instance)].get_dstport(); for (int i = 0; i < create_tunnel_req->num_tunnels; i++) { - teid_t teid=newGtpuCreateTunnel(instance, create_tunnel_req->rnti, - create_tunnel_req->incoming_rb_id[i], - create_tunnel_req->pdusession_id[i], - create_tunnel_req->outgoing_teid[i], - create_tunnel_req->dst_addr[i], dstport, - pdcp_data_req); + teid_t teid = newGtpuCreateTunnel(instance, + create_tunnel_req->rnti, + create_tunnel_req->incoming_rb_id[i], + create_tunnel_req->pdusession_id[i], + create_tunnel_req->outgoing_teid[i], + create_tunnel_req->outgoing_qfi[i], + create_tunnel_req->dst_addr[i], + dstport, + pdcp_data_req, + sdap_data_req); create_tunnel_resp->status=0; create_tunnel_resp->rnti=create_tunnel_req->rnti; create_tunnel_resp->num_tunnels=create_tunnel_req->num_tunnels; @@ -739,9 +890,7 @@ static int Gtpv1uHandleEchoReq(int h, uint16_t seq=ntohs(*(uint16_t *)(msgHdr+1)); LOG_D(GTPU, "[%d] Received a echo request, TEID: %d, seq: %hu\n", h, msgHdr->teid, seq); uint8_t recovery[2]= {14,0}; - return gtpv1uCreateAndSendMsg(h, peerIp, peerPort, GTP_ECHO_RSP, ntohl(msgHdr->teid), - recovery, sizeof recovery, - 1, 0, 0, seq, 0, 0); + return gtpv1uCreateAndSendMsg(h, peerIp, peerPort, GTP_ECHO_RSP, ntohl(msgHdr->teid), recovery, sizeof recovery, true, false, seq, 0, NO_MORE_EXT_HDRS, NULL, 0); } static int Gtpv1uHandleError(int h, @@ -850,26 +999,63 @@ static int Gtpv1uHandleGpdu(int h, return GTPNOK; } - int offset=sizeof(Gtpv1uMsgHeaderT); - - uint8_t qfi = 0; - boolean_t rqi = FALSE; - - if( msgHdr->E || msgHdr->S || msgHdr->PN){ - Gtpv1uMsgHeaderOptFieldsT *msgHdrOpt = (Gtpv1uMsgHeaderOptFieldsT *)(msgBuf+offset); - offset+=sizeof(Gtpv1uMsgHeaderOptFieldsT); - if( msgHdr->E && msgHdrOpt->NextExtHeaderType == PDU_SESSION_CONTAINER){ - Gtpv1uExtHeaderT *msgHdrExt = (Gtpv1uExtHeaderT *)(msgBuf+offset); - offset+=msgHdrExt->ExtHeaderLen*EXT_HDR_LNTH_OCTET_UNITS; - qfi = msgHdrExt->pdusession_cntr.QFI; - rqi = msgHdrExt->pdusession_cntr.RQI; - - /* - * Check if the next extension header type of GTP extension header is set to 0 - * We can not put it in the struct Gtpv1uExtHeaderT because the length is dynamic. - */ - if(*(msgBuf+offset-1) != NO_MORE_EXT_HDRS) - LOG_W(GTPU, "Warning - Next extension header is not zero, handle it \n"); + /* see TS 29.281 5.1 */ + //Minimum length of GTP-U header if non of the optional fields are present + int offset = sizeof(Gtpv1uMsgHeaderT); + + uint8_t qfi = -1; + bool rqi = false; + uint32_t NR_PDCP_PDU_SN = 0; + + /* if E, S, or PN is set then there are 4 more bytes of header */ + if( msgHdr->E || msgHdr->S ||msgHdr->PN) + offset += 4; + + if (msgHdr->E) { + int next_extension_header_type = msgBuf[offset - 1]; + int extension_header_length; + + while (next_extension_header_type != NO_MORE_EXT_HDRS) { + extension_header_length = msgBuf[offset]; + switch (next_extension_header_type) { + case PDU_SESSION_CONTAINER: { + PDUSessionContainerT *pdusession_cntr = (PDUSessionContainerT *)(msgBuf + offset + 1); + qfi = pdusession_cntr->QFI; + rqi = pdusession_cntr->Reflective_QoS_activation; + break; + } + case NR_RAN_CONTAINER: { + uint8_t PDU_type = (msgBuf[offset+1]>>4) & 0x0f; + if (PDU_type == 0){ //DL USER Data Format + int additional_offset = 6; //Additional offset capturing the first non-mandatory octet (TS 38.425, Figure 5.5.2.1-1) + if(msgBuf[offset+1]>>2 & 0x1){ //DL Discard Blocks flag is present + LOG_I(GTPU, "DL User Data: DL Discard Blocks handling not enabled\n"); + additional_offset = additional_offset + 9; //For the moment ignore + } + if(msgBuf[offset+1]>>1 & 0x1){ //DL Flush flag is present + LOG_I(GTPU, "DL User Data: DL Flush handling not enabled\n"); + additional_offset = additional_offset + 3; //For the moment ignore + } + if((msgBuf[offset+2]>>3)& 0x1){ //"Report delivered" enabled (TS 38.425, 5.4) + /*Store the NR PDCP PDU SN for which a delivery status report shall be generated once the + *PDU gets forwarded to the lower layers*/ + //NR_PDCP_PDU_SN = msgBuf[offset+6] << 16 | msgBuf[offset+7] << 8 | msgBuf[offset+8]; + NR_PDCP_PDU_SN = msgBuf[offset+additional_offset] << 16 | msgBuf[offset+additional_offset+1] << 8 | msgBuf[offset+additional_offset+2]; + LOG_D(GTPU, " NR_PDCP_PDU_SN: %u \n", NR_PDCP_PDU_SN); + } + } + else{ + LOG_W(GTPU, "NR-RAN container type: %d not supported \n", PDU_type); + } + break; + } + default: + LOG_W(GTPU, "unhandled extension 0x%2.2x, skipping\n", next_extension_header_type); + break; + } + + offset += extension_header_length * EXT_HDR_LNTH_OCTET_UNITS; + next_extension_header_type = msgBuf[offset - 1]; } } @@ -896,7 +1082,7 @@ static int Gtpv1uHandleGpdu(int h, const uint32_t destinationL2Id=0; pthread_mutex_unlock(&globGtp.gtp_lock); - if(is_gnb && qfi){ + if (qfi != -1 && tunnel->second.callBackSDAP) { if ( !tunnel->second.callBackSDAP(&ctxt, srb_flag, rb_id, @@ -925,6 +1111,40 @@ static int Gtpv1uHandleGpdu(int h, LOG_E(GTPU,"[%d] down layer refused incoming packet\n", h); } + if(NR_PDCP_PDU_SN > 0 && NR_PDCP_PDU_SN %5 ==0){ + LOG_D (GTPU, "Create and send DL DATA Delivery status for the previously received PDU, NR_PDCP_PDU_SN: %u \n", NR_PDCP_PDU_SN); + int rlc_tx_buffer_space = nr_rlc_get_available_tx_space(ctxt.rnti, rb_id); + LOG_D(GTPU, "Available buffer size in RLC for Tx: %d \n", rlc_tx_buffer_space); + /*Total size of DDD_status PDU = 1 octet to report extension header length + * size of mandatory part + 3 octets for highest transmitted/delivered PDCP SN + * 1 octet for padding + 1 octet for next extension header type, + * according to TS 38.425: Fig. 5.5.2.2-1 and section 5.5.3.24*/ + extensionHeader_t *extensionHeader; + extensionHeader = (extensionHeader_t *) calloc(1, sizeof(extensionHeader_t)) ; + extensionHeader->buffer[0] = (1+sizeof(DlDataDeliveryStatus_flagsT)+3+1+1)/4; + DlDataDeliveryStatus_flagsT DlDataDeliveryStatus; + DlDataDeliveryStatus.deliveredPdcpSn = 0; + DlDataDeliveryStatus.transmittedPdcpSn= 1; + DlDataDeliveryStatus.pduType = 1; + DlDataDeliveryStatus.drbBufferSize = htonl(rlc_tx_buffer_space); //htonl(10000000); //hardcoded for now but normally we should extract it from RLC + memcpy(extensionHeader->buffer+1, &DlDataDeliveryStatus, sizeof(DlDataDeliveryStatus_flagsT)); + uint8_t offset = sizeof(DlDataDeliveryStatus_flagsT)+1; + + extensionHeader->buffer[offset] = (NR_PDCP_PDU_SN >> 16) & 0xff; + extensionHeader->buffer[offset+1] = (NR_PDCP_PDU_SN >> 8) & 0xff; + extensionHeader->buffer[offset+2] = NR_PDCP_PDU_SN & 0xff; + LOG_D(GTPU, "Octets reporting NR_PDCP_PDU_SN, extensionHeader->buffer[offset]: %u, extensionHeader->buffer[offset+1]:%u, extensionHeader->buffer[offset+2]:%u \n", extensionHeader->buffer[offset], extensionHeader->buffer[offset+1],extensionHeader->buffer[offset+2]); + extensionHeader->buffer[offset+3] = 0x00; //Padding octet + extensionHeader->buffer[offset+4] = 0x00; //No more extension headers + /*Total size of DDD_status PDU = size of mandatory part + + * 3 octets for highest transmitted/delivered PDCP SN + + * 1 octet for padding + 1 octet for next extension header type, + * according to TS 38.425: Fig. 5.5.2.2-1 and section 5.5.3.24*/ + extensionHeader->length = 1+sizeof(DlDataDeliveryStatus_flagsT)+3+1+1; + gtpv1uCreateAndSendMsg( + h, peerIp, peerPort, GTP_GPDU, inst->te2ue_mapping[ntohl(msgHdr->teid)].outgoing_teid, NULL, 0, false, false, 0, 0, NR_RAN_CONTAINER, extensionHeader->buffer, extensionHeader->length); + } + LOG_D(GTPU,"[%d] Received a %d bytes packet for: teid:%x\n", h, msgBufLen-offset, ntohl(msgHdr->teid)); @@ -1009,6 +1229,12 @@ void *gtpv1uTask(void *args) { } break; + case GTPV1U_DU_BUFFER_REPORT_REQ:{ + gtpv1uSendDlDeliveryStatus(compatInst(ITTI_MSG_DESTINATION_INSTANCE(message_p)), + >PV1U_DU_BUFFER_REPORT_REQ(message_p)); + } + break; + case TERMINATE_MESSAGE: break; diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h index 17882ebf1e7e0f04846782a2e0733c123a5def7f..7951c4db09b8854e55c5c11213d44fc300d9db3c 100644 --- a/openair3/ocp-gtpu/gtp_itf.h +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -8,32 +8,30 @@ extern "C" { #endif -typedef boolean_t (*gtpCallback)( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id); +typedef bool (*gtpCallback)(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id); -typedef boolean_t (*gtpCallbackSDAP)( - protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id, - const uint8_t qfi, - const boolean_t rqi, - const int pdusession_id); +typedef bool (*gtpCallbackSDAP)(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id, + const uint8_t qfi, + const bool rqi, + const int pdusession_id); typedef struct openAddr_s { char originHost[HOST_NAME_MAX]; @@ -43,6 +41,11 @@ typedef struct openAddr_s { instance_t originInstance; } openAddr_t; +typedef struct extensionHeader_s{ + uint8_t buffer[500]; + uint8_t length; +}extensionHeader_t; + // the init function create a gtp instance and return the gtp instance id // the parameter originInstance will be sent back in each message from gtp to the creator void gtpv1uReceiver(int h); @@ -63,8 +66,16 @@ int gtpv1u_create_x2u_tunnel( // New API -teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer_id, int outgoing_rb_id, teid_t teid, - transport_layer_addr_t remoteAddr, int port, gtpCallback callBack); +teid_t newGtpuCreateTunnel(instance_t instance, + rnti_t rnti, + int incoming_bearer_id, + int outgoing_rb_id, + teid_t teid, + int outgoing_qfi, + transport_layer_addr_t remoteAddr, + int port, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP); void GtpuUpdateTunnelOutgoingTeid(instance_t instance, rnti_t rnti, ebi_t bearer_id, teid_t newOutgoingTeid); int newGtpuDeleteAllTunnels(instance_t instance, rnti_t rnti); int newGtpuDeleteTunnels(instance_t instance, rnti_t rnti, int nbTunnels, pdusessionid_t *pdusession_id); diff --git a/rxsigF0.m b/rxsigF0.m deleted file mode 100644 index 3309e1aa6f53c7d6ac22df8bb7ffa40b6b1c6a80..0000000000000000000000000000000000000000 --- a/rxsigF0.m +++ /dev/null @@ -1,57345 +0,0 @@ -rxsF0 = [173 + j*(-306) --141 + j*(-130) --166 + j*(-246) --107 + j*(-42) --105 + j*(0) --179 + j*(-28) --87 + j*(186) --95 + j*(151) --1 + j*(228) -172 + j*(-62) -110 + j*(-5) --178 + j*(-33) --18 + j*(57) -9 + j*(146) --11 + j*(103) --67 + j*(64) -28 + j*(-375) --72 + j*(-75) --14 + j*(-318) -194 + j*(193) --173 + j*(-228) -295 + j*(119) -203 + j*(-179) --238 + j*(-276) --286 + j*(112) --409 + j*(95) --260 + j*(84) -72 + j*(40) -105 + j*(-120) -57 + j*(66) -58 + j*(173) --170 + j*(-189) -192 + j*(-50) --88 + j*(160) --187 + j*(-132) -120 + j*(41) -239 + j*(-115) -80 + j*(263) --45 + j*(-30) -396 + j*(192) -161 + j*(-11) --325 + j*(296) --64 + j*(-192) --181 + j*(-59) --272 + j*(192) -11 + j*(192) --215 + j*(50) -122 + j*(177) --255 + j*(26) -87 + j*(11) --86 + j*(-129) --199 + j*(199) --238 + j*(163) -29 + j*(134) -175 + j*(81) -30 + j*(-214) --344 + j*(131) -124 + j*(-252) -134 + j*(-325) -224 + j*(-78) -223 + j*(-190) --15 + j*(88) --223 + j*(128) --48 + j*(-223) --109 + j*(-209) --17 + j*(-84) -179 + j*(73) --25 + j*(-81) -6 + j*(88) -8 + j*(83) --75 + j*(38) --119 + j*(51) -15 + j*(199) -140 + j*(42) -44 + j*(-132) --247 + j*(118) -242 + j*(-82) -140 + j*(-258) --98 + j*(28) -262 + j*(107) --141 + j*(-21) -137 + j*(382) -64 + j*(-163) --81 + j*(62) -54 + j*(245) --132 + j*(75) -196 + j*(-219) --146 + j*(211) --64 + j*(64) --146 + j*(-37) --37 + j*(-94) --318 + j*(160) --237 + j*(112) --98 + j*(2) --286 + j*(209) --69 + j*(192) --52 + j*(105) --63 + j*(-35) -119 + j*(59) --19 + j*(-25) -110 + j*(54) -45 + j*(-37) -42 + j*(-107) -57 + j*(74) -190 + j*(105) -246 + j*(20) -233 + j*(93) -290 + j*(180) -232 + j*(-113) -281 + j*(243) -280 + j*(-250) -47 + j*(-245) -144 + j*(-150) --272 + j*(25) --94 + j*(163) --135 + j*(-334) -16 + j*(-211) --165 + j*(214) -88 + j*(34) -27 + j*(-36) --161 + j*(-243) -94 + j*(151) -112 + j*(-66) --180 + j*(48) --77 + j*(-64) --293 + j*(300) --42 + j*(-139) --177 + j*(91) --37 + j*(-39) --88 + j*(216) --123 + j*(1) -141 + j*(-250) -100 + j*(-148) --11 + j*(265) -30 + j*(-212) --9 + j*(146) -281 + j*(223) --166 + j*(141) --7 + j*(-51) -69 + j*(-37) --91 + j*(45) -198 + j*(-225) -560 + j*(-64) --245 + j*(-145) -194 + j*(231) --96 + j*(216) -8 + j*(-158) -117 + j*(42) --42 + j*(132) -97 + j*(178) --182 + j*(-65) --59 + j*(118) -129 + j*(-45) -75 + j*(-6) --88 + j*(20) --425 + j*(35) -140 + j*(424) --40 + j*(116) -27 + j*(-297) -123 + j*(230) -86 + j*(-293) -104 + j*(-127) -47 + j*(-89) -60 + j*(97) --23 + j*(197) --7 + j*(-93) -115 + j*(205) -271 + j*(-159) --56 + j*(159) --57 + j*(556) --48 + j*(-196) --71 + j*(-63) --353 + j*(-221) --84 + j*(-173) -30 + j*(45) --302 + j*(371) -354 + j*(-22) --233 + j*(35) --308 + j*(-202) --433 + j*(-44) --158 + j*(73) -185 + j*(-150) -48 + j*(124) --7 + j*(168) -190 + j*(78) -211 + j*(-9) --71 + j*(-193) --119 + j*(97) --234 + j*(-197) -341 + j*(-197) --346 + j*(74) -105 + j*(17) -57 + j*(-105) --161 + j*(-138) --180 + j*(180) --156 + j*(91) --9 + j*(-139) --87 + j*(165) --64 + j*(-238) -15 + j*(-221) --113 + j*(8) --331 + j*(59) -90 + j*(-150) --136 + j*(-325) -73 + j*(178) --18 + j*(170) -67 + j*(-96) -85 + j*(-37) --9 + j*(-114) --22 + j*(136) --175 + j*(165) --87 + j*(-25) --31 + j*(-152) --301 + j*(-18) -42 + j*(-54) --32 + j*(-168) --74 + j*(163) --54 + j*(-52) --76 + j*(-21) -67 + j*(73) -129 + j*(-255) --270 + j*(203) --112 + j*(-71) --106 + j*(13) -175 + j*(-194) -6 + j*(110) -115 + j*(135) --22 + j*(-50) -143 + j*(220) --17 + j*(-82) --65 + j*(204) --46 + j*(-112) -86 + j*(-199) -3 + j*(-52) -88 + j*(116) -184 + j*(227) --65 + j*(189) --54 + j*(-150) -139 + j*(206) -122 + j*(72) --71 + j*(194) --134 + j*(287) -44 + j*(-124) -13 + j*(-250) --100 + j*(95) --110 + j*(16) -233 + j*(-139) -228 + j*(-39) --252 + j*(133) --122 + j*(-129) -21 + j*(-143) --55 + j*(-144) --199 + j*(14) -110 + j*(-195) -85 + j*(-45) --243 + j*(-35) -59 + j*(-86) --361 + j*(179) -69 + j*(34) --22 + j*(42) --267 + j*(-294) -28 + j*(-84) -40 + j*(-247) --112 + j*(128) -54 + j*(182) -71 + j*(-33) --40 + j*(448) --75 + j*(-132) -10 + j*(-37) -272 + j*(-126) --209 + j*(-100) --98 + j*(58) -72 + j*(391) -25 + j*(21) --126 + j*(-110) --238 + j*(138) -227 + j*(-283) -64 + j*(-523) --42 + j*(392) -103 + j*(-288) --131 + j*(-207) -88 + j*(3) --81 + j*(382) --4 + j*(119) -177 + j*(-137) --95 + j*(228) -39 + j*(-127) --265 + j*(202) -145 + j*(66) --358 + j*(127) --320 + j*(-144) --48 + j*(-260) -119 + j*(37) --359 + j*(49) -257 + j*(-112) -112 + j*(84) -30 + j*(171) -136 + j*(-186) --250 + j*(-115) --274 + j*(-281) --37 + j*(1) -69 + j*(130) --125 + j*(-184) --315 + j*(-75) --93 + j*(104) -64 + j*(-6) -198 + j*(141) --88 + j*(18) -248 + j*(-57) --107 + j*(74) --71 + j*(26) --90 + j*(-21) --282 + j*(-201) -57 + j*(47) --15 + j*(33) --144 + j*(153) --202 + j*(-221) --124 + j*(-175) --146 + j*(-276) --74 + j*(39) --91 + j*(512) -125 + j*(213) -139 + j*(168) --233 + j*(-91) -60 + j*(-132) --36 + j*(-132) -21 + j*(105) --129 + j*(231) --283 + j*(191) -320 + j*(134) --171 + j*(70) --133 + j*(66) -189 + j*(47) -188 + j*(-88) --16 + j*(263) --44 + j*(4) -93 + j*(-2) -33 + j*(2) -30 + j*(211) --114 + j*(-76) -54 + j*(12) --128 + j*(-8) --23 + j*(265) --235 + j*(224) --56 + j*(260) -30 + j*(106) --150 + j*(-223) --37 + j*(-291) --175 + j*(177) --165 + j*(259) --206 + j*(63) -131 + j*(-61) --43 + j*(-186) --90 + j*(14) -79 + j*(-190) --127 + j*(115) -48 + j*(28) --5 + j*(17) --28 + j*(47) -163 + j*(135) -44 + j*(-125) --86 + j*(275) -1 + j*(117) -49 + j*(-62) -147 + j*(80) -85 + j*(84) --31 + j*(-101) -243 + j*(150) --181 + j*(-219) --138 + j*(-10) --214 + j*(-151) -27 + j*(-88) -211 + j*(86) --162 + j*(-350) --455 + j*(77) -237 + j*(30) -18 + j*(189) --131 + j*(119) -18 + j*(96) -85 + j*(78) -182 + j*(155) -6 + j*(250) -195 + j*(-153) --74 + j*(-51) -44 + j*(-60) --234 + j*(221) -359 + j*(-139) --228 + j*(291) --28 + j*(173) --147 + j*(-59) --357 + j*(100) --86 + j*(464) --113 + j*(-74) --282 + j*(356) -16 + j*(-52) -204 + j*(-316) -258 + j*(178) --75 + j*(100) --113 + j*(83) -158 + j*(309) -65 + j*(-170) -91 + j*(-125) --151 + j*(318) --52 + j*(-18) --138 + j*(176) --226 + j*(30) --177 + j*(39) --150 + j*(-13) -35 + j*(-183) -204 + j*(-308) -186 + j*(-243) --115 + j*(-71) -66 + j*(55) --88 + j*(-128) --109 + j*(195) --244 + j*(-90) -175 + j*(-177) -231 + j*(-194) --59 + j*(101) -23 + j*(-8) --117 + j*(209) --16 + j*(-97) -4 + j*(190) --28 + j*(-67) --94 + j*(3) --54 + j*(-21) --27 + j*(83) --127 + j*(-21) -187 + j*(-289) -3 + j*(-82) --1 + j*(-223) --168 + j*(232) --148 + j*(163) -274 + j*(-324) --156 + j*(-82) -384 + j*(162) --91 + j*(94) --37 + j*(10) --66 + j*(330) --85 + j*(-8) -62 + j*(216) --98 + j*(95) -126 + j*(189) -196 + j*(-243) -81 + j*(-42) --250 + j*(-2) -118 + j*(146) --1 + j*(-98) -88 + j*(-234) --151 + j*(25) -175 + j*(235) -36 + j*(-182) --108 + j*(69) -105 + j*(-38) --175 + j*(-36) --327 + j*(-45) -80 + j*(268) -13 + j*(-43) --87 + j*(57) --70 + j*(-112) -192 + j*(71) --369 + j*(-114) -224 + j*(341) --144 + j*(-145) -262 + j*(105) --91 + j*(-185) --6 + j*(116) --344 + j*(-245) -90 + j*(-101) -147 + j*(-123) --76 + j*(-71) -6 + j*(197) --44 + j*(-130) -21 + j*(-84) -448 + j*(74) -175 + j*(-3) --175 + j*(-156) --18 + j*(-110) --95 + j*(-250) --107 + j*(172) --110 + j*(157) -132 + j*(6) -47 + j*(146) -212 + j*(-167) -95 + j*(40) --239 + j*(-44) -97 + j*(134) --104 + j*(-193) --363 + j*(-244) -86 + j*(-1) -72 + j*(-13) -62 + j*(157) -214 + j*(-103) --161 + j*(-3) --252 + j*(-139) -147 + j*(39) -30 + j*(-73) --100 + j*(-203) -159 + j*(-250) --323 + j*(-118) --35 + j*(-88) --76 + j*(-105) --24 + j*(28) --194 + j*(-233) --272 + j*(23) --204 + j*(89) --83 + j*(-110) --88 + j*(110) -254 + j*(-103) -32 + j*(136) -92 + j*(-226) --92 + j*(-203) --136 + j*(94) --283 + j*(-192) -161 + j*(272) --102 + j*(30) -71 + j*(-71) -158 + j*(58) --71 + j*(-139) -220 + j*(-131) -225 + j*(-135) --222 + j*(332) --296 + j*(-165) --156 + j*(-104) --216 + j*(164) -305 + j*(-68) --102 + j*(47) --25 + j*(66) -28 + j*(250) -120 + j*(-64) --120 + j*(-134) --42 + j*(114) -18 + j*(32) --83 + j*(157) -115 + j*(-25) --247 + j*(-110) --53 + j*(206) -170 + j*(-30) --86 + j*(100) -384 + j*(119) --332 + j*(-5) --37 + j*(163) -74 + j*(285) -139 + j*(-320) --286 + j*(18) -21 + j*(313) -125 + j*(50) --30 + j*(530) -153 + j*(24) -115 + j*(-141) --392 + j*(-131) -194 + j*(-179) -167 + j*(211) -161 + j*(133) -101 + j*(-263) --185 + j*(-81) --6 + j*(240) -257 + j*(71) --30 + j*(68) --143 + j*(29) -124 + j*(154) -296 + j*(-67) -360 + j*(-25) -187 + j*(-21) --70 + j*(409) --95 + j*(39) -53 + j*(161) --158 + j*(64) --141 + j*(112) -414 + j*(-13) --153 + j*(-59) --189 + j*(-54) --69 + j*(19) -1 + j*(-12) -191 + j*(192) --133 + j*(-95) --245 + j*(232) -86 + j*(-66) --173 + j*(129) -63 + j*(131) --348 + j*(-260) -143 + j*(-136) --97 + j*(-107) -135 + j*(58) -184 + j*(-80) --7 + j*(363) --285 + j*(-198) --103 + j*(290) -134 + j*(87) --22 + j*(-163) -66 + j*(-226) -182 + j*(54) --204 + j*(-52) --194 + j*(161) --63 + j*(-117) -61 + j*(98) -49 + j*(-33) --152 + j*(40) -177 + j*(-91) -22 + j*(-106) -89 + j*(-54) -37 + j*(-148) -286 + j*(-67) --114 + j*(69) -13 + j*(127) --218 + j*(-8) --154 + j*(19) -73 + j*(138) --132 + j*(16) -185 + j*(117) --136 + j*(351) --121 + j*(98) -184 + j*(-65) -187 + j*(51) -119 + j*(68) --85 + j*(-50) -145 + j*(-25) --8 + j*(61) -137 + j*(325) --124 + j*(-22) -326 + j*(-175) --25 + j*(86) -279 + j*(-95) -8 + j*(159) --4 + j*(186) -390 + j*(-138) --162 + j*(-42) --28 + j*(114) -153 + j*(44) -340 + j*(-112) --300 + j*(-58) --86 + j*(-173) -267 + j*(-119) -209 + j*(74) --279 + j*(105) --37 + j*(-37) --59 + j*(80) --148 + j*(-163) -81 + j*(-156) --163 + j*(80) --73 + j*(378) --189 + j*(190) --35 + j*(-102) --49 + j*(-172) --177 + j*(-221) --4 + j*(215) --297 + j*(1) --94 + j*(-299) -129 + j*(-374) --38 + j*(-16) --21 + j*(-97) --215 + j*(-75) -147 + j*(111) --173 + j*(-72) -92 + j*(-138) -110 + j*(132) -28 + j*(16) --143 + j*(-182) --109 + j*(325) --30 + j*(128) --200 + j*(-168) --148 + j*(-261) -132 + j*(-63) --30 + j*(-14) --238 + j*(-55) --67 + j*(26) --214 + j*(1) --180 + j*(-286) --147 + j*(-66) -205 + j*(41) -152 + j*(-89) -35 + j*(148) --112 + j*(38) -156 + j*(-81) --177 + j*(104) --194 + j*(307) --46 + j*(-199) --290 + j*(35) --170 + j*(28) --23 + j*(214) --78 + j*(-90) --52 + j*(249) --140 + j*(-72) -175 + j*(-34) -103 + j*(115) -266 + j*(-186) -70 + j*(-192) --204 + j*(94) -18 + j*(287) --173 + j*(289) -136 + j*(216) --98 + j*(164) --37 + j*(185) --147 + j*(59) --105 + j*(-132) -51 + j*(139) -68 + j*(165) --330 + j*(-124) --30 + j*(-76) -5 + j*(-193) -209 + j*(-233) -63 + j*(117) --260 + j*(-180) --34 + j*(182) -40 + j*(-52) -97 + j*(-188) --62 + j*(-71) --13 + j*(-250) --15 + j*(234) -243 + j*(-193) -26 + j*(-392) --129 + j*(69) --143 + j*(-115) --108 + j*(56) --52 + j*(282) --7 + j*(-90) -37 + j*(-105) --615 + j*(-199) --74 + j*(85) --322 + j*(-64) -69 + j*(-165) --70 + j*(101) -29 + j*(92) --150 + j*(-327) -54 + j*(89) --398 + j*(186) --102 + j*(-121) --269 + j*(-71) -52 + j*(-62) -170 + j*(-125) -6 + j*(-69) --76 + j*(-327) -35 + j*(139) --3 + j*(-87) --322 + j*(167) -4 + j*(-26) -184 + j*(160) --178 + j*(-75) -109 + j*(62) -50 + j*(54) --64 + j*(-115) --371 + j*(-247) --124 + j*(-45) --211 + j*(-123) -153 + j*(86) --222 + j*(-161) --163 + j*(-173) --17 + j*(263) -171 + j*(27) -287 + j*(105) -31 + j*(-233) --8 + j*(-81) -37 + j*(120) --8 + j*(21) -3 + j*(-138) -95 + j*(202) -511 + j*(81) --117 + j*(-196) -35 + j*(28) --136 + j*(-301) -182 + j*(-140) --60 + j*(-66) --206 + j*(-111) -231 + j*(27) -48 + j*(49) -206 + j*(315) -86 + j*(93) -131 + j*(-232) --161 + j*(6) -22 + j*(306) --307 + j*(-81) --170 + j*(87) -173 + j*(1) --286 + j*(-155) --278 + j*(-192) -10 + j*(-42) --153 + j*(202) -377 + j*(35) -8 + j*(-47) --54 + j*(-46) -138 + j*(-201) -26 + j*(-49) -235 + j*(-73) --143 + j*(-291) --103 + j*(-30) -18 + j*(-281) -311 + j*(122) -9 + j*(-27) --240 + j*(50) --110 + j*(209) -187 + j*(-209) -68 + j*(247) -498 + j*(-59) -161 + j*(-189) --132 + j*(72) --127 + j*(18) --193 + j*(-185) --127 + j*(-276) --104 + j*(235) --26 + j*(165) -148 + j*(-181) -87 + j*(-107) --177 + j*(136) -173 + j*(2) --298 + j*(-63) -218 + j*(29) --330 + j*(-167) -110 + j*(127) --18 + j*(-42) --85 + j*(153) --92 + j*(-119) -23 + j*(115) -149 + j*(-76) --132 + j*(85) --163 + j*(-52) --139 + j*(303) -151 + j*(113) -264 + j*(74) -48 + j*(115) --38 + j*(-9) --232 + j*(262) -412 + j*(123) -28 + j*(108) --53 + j*(-95) --79 + j*(184) --252 + j*(192) -170 + j*(39) -220 + j*(249) --5 + j*(-8) -125 + j*(27) -147 + j*(-80) -25 + j*(-272) -52 + j*(47) -248 + j*(-56) --84 + j*(-51) --93 + j*(-395) --179 + j*(221) --110 + j*(108) -13 + j*(26) -332 + j*(336) -31 + j*(-141) --2 + j*(76) -334 + j*(-79) -28 + j*(86) -307 + j*(-129) --251 + j*(197) --21 + j*(-36) --117 + j*(71) --279 + j*(42) -220 + j*(216) -135 + j*(-161) -345 + j*(-245) -40 + j*(-155) --61 + j*(159) -105 + j*(52) -278 + j*(-63) --40 + j*(35) --47 + j*(326) --171 + j*(-151) -83 + j*(177) --250 + j*(-70) -20 + j*(-68) -87 + j*(-123) --325 + j*(-98) --3 + j*(81) --21 + j*(165) -97 + j*(295) -554 + j*(168) --192 + j*(-154) -14 + j*(-11) --201 + j*(67) --163 + j*(153) --23 + j*(-153) --44 + j*(-7) --18 + j*(63) --110 + j*(-35) -471 + j*(-202) -267 + j*(-194) --140 + j*(-358) --204 + j*(-94) --25 + j*(-147) -59 + j*(199) -58 + j*(-13) --36 + j*(-114) -115 + j*(-163) -190 + j*(226) --142 + j*(-144) -51 + j*(-93) -68 + j*(-77) -1 + j*(-323) -95 + j*(-72) --112 + j*(3) -202 + j*(284) --261 + j*(18) --358 + j*(122) --129 + j*(-37) -80 + j*(-91) -59 + j*(132) -274 + j*(-385) -54 + j*(-131) --49 + j*(-127) --94 + j*(-332) -276 + j*(-44) -332 + j*(139) -13 + j*(-103) --63 + j*(137) -115 + j*(-137) --117 + j*(233) -10 + j*(-170) --358 + j*(-182) --37 + j*(15) -68 + j*(9) -342 + j*(-268) --127 + j*(-199) -141 + j*(-452) --265 + j*(1) --180 + j*(236) --18 + j*(4) -35 + j*(228) --30 + j*(8) -182 + j*(-211) --233 + j*(0) --79 + j*(-53) --159 + j*(100) --29 + j*(-131) --22 + j*(27) --136 + j*(165) -44 + j*(146) --162 + j*(21) -60 + j*(-158) --127 + j*(-2) --11 + j*(191) --139 + j*(9) -315 + j*(115) -175 + j*(-193) --45 + j*(250) -36 + j*(2) -141 + j*(-198) --307 + j*(2) -144 + j*(-59) -122 + j*(-27) --211 + j*(-483) -185 + j*(58) -39 + j*(127) --238 + j*(-109) -106 + j*(345) -76 + j*(33) -239 + j*(207) --109 + j*(-249) --146 + j*(45) --38 + j*(-150) -78 + j*(-186) -8 + j*(71) --207 + j*(-255) -85 + j*(16) --23 + j*(-153) -82 + j*(-11) --10 + j*(116) -162 + j*(-201) -66 + j*(-116) -277 + j*(163) -102 + j*(-358) -54 + j*(10) -37 + j*(-112) -127 + j*(-64) --74 + j*(-93) --54 + j*(214) -149 + j*(-37) --269 + j*(-66) --13 + j*(-220) --120 + j*(76) -97 + j*(75) -238 + j*(-78) -263 + j*(-293) --57 + j*(-131) -127 + j*(-202) -235 + j*(-105) -226 + j*(-18) --107 + j*(-286) -194 + j*(-118) -104 + j*(-121) -21 + j*(117) -380 + j*(92) -22 + j*(-190) -79 + j*(37) -175 + j*(180) -42 + j*(-70) -40 + j*(-174) --36 + j*(-141) --165 + j*(92) -9 + j*(-335) -328 + j*(-194) --198 + j*(-147) -342 + j*(-129) -71 + j*(-201) -176 + j*(-66) -16 + j*(-255) -179 + j*(-119) -89 + j*(133) -144 + j*(-78) -106 + j*(235) -175 + j*(-324) --68 + j*(315) --265 + j*(-374) --28 + j*(14) --213 + j*(106) -106 + j*(-163) -49 + j*(-71) --151 + j*(6) --421 + j*(119) --244 + j*(23) -81 + j*(-57) --259 + j*(-230) -177 + j*(101) --48 + j*(-308) -147 + j*(57) -152 + j*(47) --194 + j*(-25) --116 + j*(356) --68 + j*(149) -7 + j*(-132) --126 + j*(-159) --177 + j*(272) -226 + j*(-257) --158 + j*(51) --73 + j*(214) -47 + j*(-237) -161 + j*(250) -83 + j*(105) -103 + j*(35) -99 + j*(81) --6 + j*(0) --122 + j*(39) --116 + j*(-209) --172 + j*(-250) -179 + j*(-8) --174 + j*(134) --71 + j*(-194) -105 + j*(257) --124 + j*(100) -33 + j*(-117) --73 + j*(53) -144 + j*(-12) --185 + j*(-141) -136 + j*(110) -45 + j*(117) --7 + j*(-195) --86 + j*(172) --23 + j*(-103) --263 + j*(-26) --37 + j*(124) -166 + j*(392) --373 + j*(111) --34 + j*(-202) -63 + j*(299) -474 + j*(273) --264 + j*(-284) --119 + j*(33) -227 + j*(-117) --98 + j*(135) --47 + j*(-141) --158 + j*(-36) -160 + j*(38) --29 + j*(66) -144 + j*(-272) --171 + j*(-107) -357 + j*(-86) --231 + j*(-86) --75 + j*(-76) -216 + j*(156) --13 + j*(-187) --88 + j*(37) -119 + j*(270) -31 + j*(-77) --140 + j*(37) -21 + j*(-17) -211 + j*(-33) --287 + j*(101) --112 + j*(142) --3 + j*(-140) --91 + j*(-151) -150 + j*(-243) --64 + j*(96) --262 + j*(163) -196 + j*(-39) --126 + j*(-71) --161 + j*(102) --125 + j*(35) -292 + j*(98) --6 + j*(192) -107 + j*(-71) -83 + j*(-193) -272 + j*(-25) -235 + j*(67) --87 + j*(-159) --54 + j*(-118) --279 + j*(-4) -29 + j*(-20) -132 + j*(314) --73 + j*(-148) --470 + j*(86) -262 + j*(-260) --76 + j*(-42) -256 + j*(64) --18 + j*(-144) -40 + j*(-151) -75 + j*(-166) --196 + j*(21) --45 + j*(184) -121 + j*(18) --89 + j*(-148) --170 + j*(-18) -338 + j*(-150) --276 + j*(221) --177 + j*(236) -139 + j*(-134) -139 + j*(213) -33 + j*(233) --53 + j*(16) --219 + j*(-206) -301 + j*(-21) -83 + j*(-59) -47 + j*(-66) -325 + j*(-275) -53 + j*(10) --25 + j*(106) -85 + j*(-86) --150 + j*(-16) --172 + j*(-122) -317 + j*(-115) -66 + j*(-1) --176 + j*(4) --47 + j*(-43) --122 + j*(-28) -79 + j*(519) --87 + j*(190) -81 + j*(-124) -149 + j*(-67) --68 + j*(-148) --154 + j*(-199) --127 + j*(94) --21 + j*(-108) --185 + j*(155) --327 + j*(223) -127 + j*(27) -140 + j*(118) -260 + j*(-68) --228 + j*(200) --431 + j*(-226) -97 + j*(153) -68 + j*(25) --226 + j*(245) --83 + j*(133) -23 + j*(45) -70 + j*(52) --4 + j*(-66) --137 + j*(71) --110 + j*(78) -95 + j*(-11) -93 + j*(-266) --163 + j*(103) --246 + j*(-91) --9 + j*(-296) -177 + j*(-14) --151 + j*(-157) -60 + j*(73) -54 + j*(308) -165 + j*(-85) -106 + j*(-66) --205 + j*(-183) -45 + j*(107) -71 + j*(-59) -249 + j*(27) -10 + j*(168) --153 + j*(-134) --40 + j*(208) --214 + j*(156) -77 + j*(220) -115 + j*(103) -52 + j*(-8) --93 + j*(133) --163 + j*(78) -283 + j*(22) --500 + j*(-91) --42 + j*(-286) -25 + j*(143) --62 + j*(350) -303 + j*(157) --164 + j*(-109) -36 + j*(-296) -166 + j*(19) -298 + j*(161) -99 + j*(-253) -37 + j*(-6) --117 + j*(245) -191 + j*(-123) -153 + j*(-14) -107 + j*(77) --71 + j*(-195) -266 + j*(-438) -163 + j*(3) --202 + j*(-173) --95 + j*(62) -11 + j*(337) -33 + j*(-120) -206 + j*(-425) --189 + j*(-49) -183 + j*(118) --66 + j*(144) --214 + j*(-160) -88 + j*(-28) --49 + j*(102) --262 + j*(-225) --136 + j*(-174) --87 + j*(265) --43 + j*(-2) -68 + j*(36) -47 + j*(-197) --139 + j*(194) -14 + j*(332) -89 + j*(-95) --348 + j*(-112) -122 + j*(-240) -221 + j*(132) -170 + j*(-24) -310 + j*(-73) --103 + j*(-392) -61 + j*(-144) -112 + j*(-128) -73 + j*(52) -48 + j*(435) -224 + j*(169) -116 + j*(-322) -91 + j*(-1) --40 + j*(243) -72 + j*(-96) -159 + j*(-83) -69 + j*(30) --173 + j*(316) -322 + j*(-42) -99 + j*(208) -76 + j*(-222) --35 + j*(-66) -4 + j*(-345) --223 + j*(-115) --37 + j*(212) --119 + j*(6) --23 + j*(-83) --25 + j*(-12) --78 + j*(-47) -166 + j*(69) -116 + j*(72) --60 + j*(105) -165 + j*(53) -83 + j*(-57) --48 + j*(337) -35 + j*(-71) --260 + j*(124) --185 + j*(49) --117 + j*(-358) -138 + j*(-20) --103 + j*(-228) --87 + j*(105) --141 + j*(-50) -160 + j*(124) --448 + j*(42) --87 + j*(36) --227 + j*(-343) --188 + j*(-226) --101 + j*(-183) --8 + j*(-93) --264 + j*(-92) -233 + j*(57) -5 + j*(6) --47 + j*(122) -46 + j*(11) --13 + j*(-95) --35 + j*(60) -203 + j*(-5) --267 + j*(25) -112 + j*(-79) -329 + j*(-30) -111 + j*(-98) --238 + j*(286) --76 + j*(-166) -103 + j*(-232) --41 + j*(-90) -28 + j*(182) -190 + j*(-57) -203 + j*(-90) --51 + j*(-117) -74 + j*(120) --161 + j*(-360) -72 + j*(-57) -296 + j*(-36) -146 + j*(-111) -149 + j*(-75) --59 + j*(-81) -104 + j*(-30) -198 + j*(124) --120 + j*(-214) --98 + j*(63) --127 + j*(-165) -284 + j*(-8) --92 + j*(-310) --368 + j*(105) --314 + j*(-363) -184 + j*(265) --100 + j*(-36) --134 + j*(-56) --158 + j*(121) -72 + j*(-204) -130 + j*(44) --209 + j*(-211) -62 + j*(-212) -177 + j*(100) -78 + j*(-333) --42 + j*(-40) --37 + j*(125) -57 + j*(21) -182 + j*(-21) -3 + j*(-171) -243 + j*(-354) -344 + j*(57) --157 + j*(-167) -121 + j*(59) -151 + j*(145) --162 + j*(-107) -181 + j*(-11) --32 + j*(383) -86 + j*(7) --135 + j*(-260) --79 + j*(-11) --136 + j*(-334) -66 + j*(219) -300 + j*(1) --116 + j*(-202) -186 + j*(-223) -228 + j*(400) --150 + j*(-101) -161 + j*(-204) --10 + j*(53) --236 + j*(172) -143 + j*(-182) -10 + j*(272) -55 + j*(184) -32 + j*(-390) --69 + j*(317) --37 + j*(11) --74 + j*(30) -140 + j*(-83) -53 + j*(-136) -200 + j*(-285) --189 + j*(-378) --101 + j*(-253) --25 + j*(78) -17 + j*(-104) --180 + j*(196) --148 + j*(-309) --317 + j*(119) -141 + j*(79) --41 + j*(-72) --162 + j*(-63) --65 + j*(-35) --110 + j*(49) -110 + j*(-48) -19 + j*(92) --148 + j*(14) --102 + j*(280) -139 + j*(43) --36 + j*(-207) -40 + j*(-76) -172 + j*(-279) --35 + j*(224) -414 + j*(-378) -157 + j*(-112) -529 + j*(-307) --1 + j*(-74) --11 + j*(330) -236 + j*(-36) --158 + j*(-353) --215 + j*(-29) -185 + j*(174) --8 + j*(-27) -306 + j*(170) --214 + j*(-102) --73 + j*(37) -199 + j*(-156) -230 + j*(-113) --2 + j*(-106) --80 + j*(204) -40 + j*(-276) -196 + j*(-459) --330 + j*(-98) --267 + j*(83) --15 + j*(-58) --163 + j*(403) --126 + j*(-262) --215 + j*(178) -89 + j*(121) --132 + j*(130) -154 + j*(210) --159 + j*(337) --264 + j*(161) -25 + j*(201) --21 + j*(102) --132 + j*(101) -6 + j*(98) --19 + j*(-328) -62 + j*(-122) --151 + j*(-103) --72 + j*(316) -150 + j*(-520) -438 + j*(378) -144 + j*(462) -161 + j*(15) -42 + j*(-182) --123 + j*(479) --248 + j*(145) --416 + j*(305) -34 + j*(-459) -334 + j*(133) -391 + j*(-385) --167 + j*(324) --98 + j*(104) -444 + j*(-168) -151 + j*(-241) --143 + j*(56) --148 + j*(281) --276 + j*(269) -260 + j*(-255) -173 + j*(-64) -534 + j*(206) --692 + j*(597) -173 + j*(-259) -235 + j*(346) --59 + j*(-310) -124 + j*(334) --416 + j*(-148) -438 + j*(66) --269 + j*(421) --455 + j*(235) -355 + j*(-293) --326 + j*(-148) --332 + j*(-433) --89 + j*(75) -468 + j*(-103) -376 + j*(-51) --180 + j*(12) -91 + j*(-346) --95 + j*(447) --214 + j*(281) -107 + j*(256) -179 + j*(-77) --397 + j*(-168) --208 + j*(528) --342 + j*(282) -212 + j*(-330) --327 + j*(119) -339 + j*(-146) -112 + j*(346) -361 + j*(142) --556 + j*(260) --226 + j*(-152) --368 + j*(-221) --532 + j*(-147) --494 + j*(-18) -614 + j*(-132) -274 + j*(-102) --269 + j*(-486) --263 + j*(134) --486 + j*(426) --143 + j*(-286) --215 + j*(-343) --383 + j*(-17) --139 + j*(245) -346 + j*(157) -2 + j*(60) -264 + j*(64) -304 + j*(-49) -298 + j*(-491) --375 + j*(-129) -170 + j*(109) --226 + j*(-220) -450 + j*(117) --173 + j*(221) --119 + j*(484) --325 + j*(-109) --301 + j*(-263) --227 + j*(-337) --144 + j*(-313) --93 + j*(-265) --14 + j*(-269) --456 + j*(25) --330 + j*(127) --286 + j*(351) -482 + j*(-336) --387 + j*(436) --182 + j*(260) --327 + j*(-333) --502 + j*(-140) --131 + j*(-227) --261 + j*(-309) -183 + j*(195) --160 + j*(-465) --325 + j*(-431) -212 + j*(-549) -19 + j*(-120) -73 + j*(-1) --316 + j*(347) -192 + j*(265) --192 + j*(-124) -260 + j*(417) -431 + j*(-404) -192 + j*(-508) --54 + j*(-424) -370 + j*(18) --393 + j*(-101) -434 + j*(-268) -50 + j*(-37) -504 + j*(-91) -462 + j*(337) --223 + j*(-328) -298 + j*(-308) -140 + j*(-303) --208 + j*(-406) -378 + j*(-223) --325 + j*(105) --467 + j*(-122) -297 + j*(279) --589 + j*(-381) -252 + j*(185) -161 + j*(-177) -348 + j*(605) --329 + j*(116) -122 + j*(-226) --303 + j*(-57) -357 + j*(-264) --152 + j*(-261) --234 + j*(-112) --66 + j*(37) -239 + j*(446) --20 + j*(170) --202 + j*(72) --132 + j*(-164) --121 + j*(-69) --368 + j*(-541) --16 + j*(356) --226 + j*(-168) --274 + j*(-315) -606 + j*(-180) --187 + j*(-28) --444 + j*(333) --466 + j*(-235) --121 + j*(-71) --236 + j*(-49) -506 + j*(-332) -218 + j*(248) --22 + j*(-289) -308 + j*(-8) --85 + j*(414) --154 + j*(360) -46 + j*(-332) -199 + j*(10) --243 + j*(485) --368 + j*(-624) --367 + j*(170) --339 + j*(274) -895 + j*(286) -148 + j*(-251) -167 + j*(156) -195 + j*(205) -27 + j*(-98) -86 + j*(-226) --197 + j*(-206) -417 + j*(-226) -308 + j*(503) -401 + j*(-250) --139 + j*(158) -108 + j*(190) -462 + j*(257) -14 + j*(-387) -360 + j*(155) --435 + j*(-99) -361 + j*(416) -258 + j*(-62) -25 + j*(-333) -66 + j*(352) -546 + j*(-286) --180 + j*(-458) -280 + j*(-151) -72 + j*(-216) --368 + j*(403) -464 + j*(527) --344 + j*(-60) --129 + j*(516) --279 + j*(348) --249 + j*(257) -95 + j*(226) -180 + j*(170) --97 + j*(-238) --234 + j*(-164) -148 + j*(-344) --190 + j*(-359) -152 + j*(537) -187 + j*(-93) --264 + j*(311) -100 + j*(115) -329 + j*(-129) --264 + j*(495) -281 + j*(296) --216 + j*(-100) -255 + j*(635) --410 + j*(324) -368 + j*(349) --515 + j*(-427) --296 + j*(-91) --89 + j*(-357) -23 + j*(-220) --39 + j*(-482) -366 + j*(613) -359 + j*(44) -270 + j*(-241) -146 + j*(-653) --220 + j*(441) -269 + j*(125) --350 + j*(321) -284 + j*(12) --209 + j*(-60) -305 + j*(144) --368 + j*(272) -468 + j*(-231) -176 + j*(12) --149 + j*(-216) -424 + j*(-84) --462 + j*(-520) -349 + j*(-377) --361 + j*(166) -165 + j*(238) --78 + j*(201) --188 + j*(330) --70 + j*(-25) --220 + j*(330) --206 + j*(308) -378 + j*(-181) --203 + j*(-356) -501 + j*(-574) -63 + j*(134) --493 + j*(-103) --26 + j*(-341) --390 + j*(158) -69 + j*(249) -279 + j*(358) -441 + j*(-253) --142 + j*(142) --346 + j*(-387) -332 + j*(-606) -187 + j*(240) -431 + j*(-35) -308 + j*(-181) -240 + j*(-338) -240 + j*(-168) --429 + j*(-134) -161 + j*(-89) --460 + j*(-346) --382 + j*(247) --521 + j*(-66) -99 + j*(318) --193 + j*(-20) -148 + j*(551) -366 + j*(200) -560 + j*(-170) -281 + j*(280) --462 + j*(-173) --424 + j*(66) -190 + j*(354) --135 + j*(-346) --283 + j*(-282) -306 + j*(-280) -308 + j*(341) -57 + j*(-380) --439 + j*(-147) -46 + j*(-188) --189 + j*(136) --167 + j*(281) --73 + j*(-352) -286 + j*(165) --353 + j*(152) -255 + j*(-443) -458 + j*(300) -126 + j*(-267) --147 + j*(430) -756 + j*(232) --462 + j*(-200) --246 + j*(368) -392 + j*(501) -593 + j*(-118) --341 + j*(274) -240 + j*(221) --474 + j*(-129) -277 + j*(418) --134 + j*(231) --302 + j*(115) -101 + j*(337) --122 + j*(-20) -503 + j*(-217) -473 + j*(-235) --338 + j*(-158) --43 + j*(472) --428 + j*(-216) --344 + j*(75) --728 + j*(233) --86 + j*(6) -337 + j*(-549) --318 + j*(4) --322 + j*(177) -141 + j*(-152) -445 + j*(85) -260 + j*(178) -54 + j*(128) --45 + j*(103) --320 + j*(307) --640 + j*(-346) --98 + j*(445) --356 + j*(-291) -173 + j*(229) --5 + j*(130) -142 + j*(248) --248 + j*(412) --18 + j*(494) -238 + j*(195) --159 + j*(-196) -338 + j*(211) -767 + j*(-549) -516 + j*(185) -252 + j*(87) --416 + j*(387) -371 + j*(-352) --396 + j*(34) -455 + j*(34) -298 + j*(-147) --377 + j*(119) -214 + j*(-19) --242 + j*(-141) -115 + j*(305) -542 + j*(292) -58 + j*(-453) -199 + j*(-347) --431 + j*(-128) -260 + j*(-252) --175 + j*(491) -535 + j*(-119) -330 + j*(69) --240 + j*(-301) -499 + j*(525) --400 + j*(-455) -549 + j*(636) -247 + j*(-328) --293 + j*(-170) --178 + j*(270) --119 + j*(250) -183 + j*(57) -252 + j*(97) --539 + j*(-34) --353 + j*(-15) --105 + j*(-148) --272 + j*(-336) --338 + j*(-402) --396 + j*(57) -292 + j*(41) --204 + j*(-299) -281 + j*(333) -77 + j*(323) --190 + j*(-385) -426 + j*(-128) -263 + j*(282) -16 + j*(18) -327 + j*(-40) --411 + j*(-99) -387 + j*(91) --238 + j*(166) --72 + j*(11) --508 + j*(233) -244 + j*(-490) --442 + j*(216) -178 + j*(-419) -313 + j*(187) -266 + j*(-521) -390 + j*(-337) -448 + j*(-103) -425 + j*(-349) --151 + j*(310) -283 + j*(-153) -320 + j*(-281) -56 + j*(99) --202 + j*(-406) --141 + j*(-409) -121 + j*(317) -380 + j*(371) --177 + j*(-47) -361 + j*(-379) --448 + j*(-28) -296 + j*(-269) -508 + j*(-238) -659 + j*(-47) --298 + j*(-180) -104 + j*(174) -49 + j*(-67) -233 + j*(-449) -339 + j*(156) -258 + j*(-158) --181 + j*(426) -278 + j*(-175) --68 + j*(-334) -327 + j*(-599) -118 + j*(-216) -45 + j*(-304) --158 + j*(216) --257 + j*(204) -396 + j*(-415) -338 + j*(229) --194 + j*(256) --583 + j*(306) -103 + j*(-457) -185 + j*(-439) -478 + j*(66) --255 + j*(464) --145 + j*(346) --660 + j*(-47) --511 + j*(-410) --288 + j*(453) --258 + j*(250) --115 + j*(-121) -134 + j*(344) -349 + j*(-287) --503 + j*(205) --383 + j*(-410) --470 + j*(240) -325 + j*(-687) -221 + j*(-151) -426 + j*(418) -134 + j*(206) -88 + j*(-121) --111 + j*(362) --305 + j*(-182) -93 + j*(-185) --174 + j*(406) --417 + j*(240) -104 + j*(-155) -146 + j*(375) -618 + j*(146) -134 + j*(196) --393 + j*(343) --454 + j*(-76) -260 + j*(-24) -132 + j*(-68) -242 + j*(426) -106 + j*(-454) --266 + j*(-200) -337 + j*(576) -180 + j*(95) --257 + j*(116) -459 + j*(417) --129 + j*(-160) -142 + j*(-197) -219 + j*(504) -154 + j*(170) -132 + j*(185) -316 + j*(264) --440 + j*(200) -97 + j*(-3) --9 + j*(-173) -249 + j*(-28) -612 + j*(-663) --484 + j*(-26) -419 + j*(425) --228 + j*(330) -4 + j*(-297) -445 + j*(201) -519 + j*(37) -333 + j*(158) -362 + j*(45) -333 + j*(-542) -187 + j*(-188) --148 + j*(-273) --329 + j*(241) --148 + j*(-251) -423 + j*(-16) -90 + j*(-232) --293 + j*(551) --190 + j*(165) --256 + j*(-518) -143 + j*(-260) -463 + j*(-392) --295 + j*(-20) -14 + j*(-130) -2 + j*(293) --354 + j*(-299) -409 + j*(298) -185 + j*(238) -383 + j*(220) -316 + j*(-39) -177 + j*(-8) --269 + j*(-223) --332 + j*(132) --312 + j*(137) --254 + j*(-224) --279 + j*(-206) -103 + j*(276) --81 + j*(235) -106 + j*(-356) --250 + j*(170) -146 + j*(-256) -375 + j*(206) -35 + j*(285) -179 + j*(-480) --4 + j*(262) -286 + j*(339) -349 + j*(3) -262 + j*(-317) --188 + j*(314) -258 + j*(280) --60 + j*(-63) --358 + j*(-431) -355 + j*(-313) -602 + j*(-572) --97 + j*(29) --361 + j*(112) -426 + j*(-446) --334 + j*(-248) --468 + j*(-301) --134 + j*(-296) -344 + j*(-398) --33 + j*(361) -339 + j*(-470) -238 + j*(311) -455 + j*(372) --419 + j*(47) --267 + j*(-6) -313 + j*(-315) --314 + j*(148) --167 + j*(-559) -371 + j*(-467) --377 + j*(337) -535 + j*(-262) -170 + j*(-213) --719 + j*(-409) --59 + j*(155) --137 + j*(240) --403 + j*(-211) --310 + j*(-119) -405 + j*(-72) --488 + j*(136) --270 + j*(-495) -375 + j*(-124) -294 + j*(-73) -494 + j*(406) -423 + j*(311) --401 + j*(-383) -378 + j*(293) --290 + j*(-348) -111 + j*(-182) -414 + j*(523) --121 + j*(746) -129 + j*(-466) -409 + j*(-359) -342 + j*(63) --325 + j*(174) --292 + j*(103) -221 + j*(407) -298 + j*(240) --343 + j*(363) -192 + j*(-296) --291 + j*(180) --76 + j*(-33) --58 + j*(-362) --260 + j*(-202) --301 + j*(-129) -86 + j*(400) --240 + j*(337) -77 + j*(-55) -279 + j*(831) -20 + j*(-13) -305 + j*(-124) -551 + j*(99) -439 + j*(438) --194 + j*(490) -592 + j*(216) --382 + j*(228) --316 + j*(76) -98 + j*(30) -216 + j*(-286) -268 + j*(18) --13 + j*(233) --497 + j*(-483) -25 + j*(-332) -168 + j*(227) -301 + j*(143) -73 + j*(-48) --3 + j*(-291) -588 + j*(16) -192 + j*(-489) -243 + j*(76) -254 + j*(539) --380 + j*(229) -489 + j*(15) -241 + j*(131) -158 + j*(-295) -306 + j*(195) --283 + j*(428) -412 + j*(-48) -384 + j*(-260) --188 + j*(38) --104 + j*(-159) -64 + j*(142) --39 + j*(92) --73 + j*(243) -114 + j*(-292) --19 + j*(36) --160 + j*(345) -123 + j*(-62) --45 + j*(297) -299 + j*(33) -117 + j*(-93) --214 + j*(44) --345 + j*(-15) --11 + j*(-78) -204 + j*(16) -132 + j*(-22) --45 + j*(59) --220 + j*(-21) -145 + j*(-76) --124 + j*(120) -156 + j*(-31) -21 + j*(-187) --81 + j*(160) --43 + j*(-79) -114 + j*(7) -247 + j*(-122) -90 + j*(96) --132 + j*(27) -228 + j*(11) --179 + j*(40) -78 + j*(89) --513 + j*(3) --152 + j*(246) --60 + j*(211) --108 + j*(-76) --30 + j*(-112) --68 + j*(-276) -18 + j*(42) --13 + j*(-322) --76 + j*(-78) -156 + j*(48) --25 + j*(121) -106 + j*(-127) --110 + j*(257) -263 + j*(132) --168 + j*(303) -18 + j*(271) -6 + j*(-148) -133 + j*(-263) --25 + j*(130) -71 + j*(329) -406 + j*(-14) --28 + j*(-89) --214 + j*(40) --121 + j*(194) --138 + j*(-7) -107 + j*(97) -213 + j*(-98) -114 + j*(73) --233 + j*(3) --34 + j*(290) -18 + j*(-125) --28 + j*(263) --121 + j*(12) -53 + j*(-48) -95 + j*(-21) --461 + j*(13) -213 + j*(110) -223 + j*(98) --137 + j*(-126) --167 + j*(30) --60 + j*(-438) -86 + j*(-72) -94 + j*(-175) --103 + j*(111) -93 + j*(57) --177 + j*(-207) --134 + j*(130) -194 + j*(159) -25 + j*(36) -25 + j*(-231) -134 + j*(7) -117 + j*(-178) --200 + j*(214) -11 + j*(51) --337 + j*(-10) -259 + j*(-6) --61 + j*(129) --28 + j*(39) --150 + j*(-81) -67 + j*(1) --139 + j*(144) --64 + j*(-216) -107 + j*(-387) --105 + j*(93) -342 + j*(-31) --133 + j*(26) -18 + j*(-242) --230 + j*(-160) --255 + j*(-103) -288 + j*(70) -45 + j*(18) -91 + j*(-15) -95 + j*(69) -6 + j*(193) --107 + j*(-19) -264 + j*(-83) -42 + j*(-170) --48 + j*(-8) -242 + j*(4) -320 + j*(47) --75 + j*(-93) --161 + j*(45) --58 + j*(-127) -112 + j*(66) -193 + j*(224) --577 + j*(-352) --33 + j*(142) -117 + j*(72) -1 + j*(-115) --107 + j*(167) --45 + j*(187) -29 + j*(-117) -108 + j*(-128) -103 + j*(226) --436 + j*(-210) --245 + j*(54) -37 + j*(-62) -1 + j*(-59) --233 + j*(82) --101 + j*(299) -74 + j*(46) -59 + j*(-214) --245 + j*(-179) -153 + j*(-385) --86 + j*(215) --105 + j*(-47) --48 + j*(-337) -51 + j*(153) -118 + j*(159) --117 + j*(-160) -131 + j*(19) -245 + j*(74) --171 + j*(86) --31 + j*(-61) --144 + j*(179) -35 + j*(-370) -170 + j*(-76) -280 + j*(-52) --89 + j*(-163) -78 + j*(47) --345 + j*(-32) --236 + j*(-15) -204 + j*(-49) --517 + j*(-52) --93 + j*(-81) -264 + j*(18) --144 + j*(-25) -212 + j*(121) -26 + j*(-342) -165 + j*(53) -41 + j*(-14) --111 + j*(197) --179 + j*(233) -121 + j*(255) -208 + j*(-71) -187 + j*(293) -110 + j*(-317) -118 + j*(225) -250 + j*(187) -4 + j*(-260) --48 + j*(72) --195 + j*(97) -91 + j*(-210) -113 + j*(-173) --32 + j*(2) --112 + j*(-9) -373 + j*(-229) -42 + j*(-64) --106 + j*(-13) --58 + j*(25) -68 + j*(89) --93 + j*(-106) -204 + j*(-76) --177 + j*(13) --84 + j*(-198) -168 + j*(287) --218 + j*(220) --139 + j*(-203) -346 + j*(156) --194 + j*(-30) -134 + j*(-30) --124 + j*(147) --199 + j*(-285) -168 + j*(-201) -122 + j*(-271) -103 + j*(-25) -40 + j*(-42) --129 + j*(42) -119 + j*(234) -91 + j*(185) -154 + j*(-153) -114 + j*(396) -103 + j*(156) --127 + j*(-274) -122 + j*(-151) -34 + j*(112) --236 + j*(-66) -266 + j*(-33) --177 + j*(-86) --26 + j*(-129) -52 + j*(164) --59 + j*(-304) --383 + j*(-279) -146 + j*(136) -419 + j*(40) --30 + j*(113) --105 + j*(142) -213 + j*(-259) -30 + j*(363) -168 + j*(-375) --107 + j*(60) -128 + j*(199) --71 + j*(113) --95 + j*(-124) --17 + j*(48) --57 + j*(65) --76 + j*(23) --274 + j*(-206) -125 + j*(276) -98 + j*(-57) --129 + j*(-179) --58 + j*(311) -54 + j*(52) --351 + j*(226) --252 + j*(55) --142 + j*(-17) -202 + j*(107) -176 + j*(-477) --71 + j*(18) --174 + j*(125) -144 + j*(-108) --10 + j*(-19) --28 + j*(112) --26 + j*(132) --236 + j*(-8) -37 + j*(-214) -111 + j*(216) -260 + j*(70) --30 + j*(-69) --91 + j*(157) -221 + j*(-96) --162 + j*(-126) --71 + j*(110) -16 + j*(117) -128 + j*(-4) -69 + j*(35) --62 + j*(177) -143 + j*(88) --124 + j*(-195) --118 + j*(-61) -26 + j*(-187) --76 + j*(262) --21 + j*(-103) --164 + j*(-139) --73 + j*(-175) -262 + j*(-58) -44 + j*(58) -78 + j*(-43) --245 + j*(336) --28 + j*(-38) --124 + j*(-168) --320 + j*(34) --175 + j*(-11) --190 + j*(-241) -119 + j*(-78) --242 + j*(264) --91 + j*(234) --57 + j*(-42) --189 + j*(11) -130 + j*(103) -217 + j*(-100) -170 + j*(-62) --327 + j*(82) --132 + j*(-118) -19 + j*(1) -15 + j*(-6) --479 + j*(69) -38 + j*(68) -1 + j*(-229) -93 + j*(-98) -54 + j*(-93) --23 + j*(-100) -1 + j*(-197) --269 + j*(-126) -177 + j*(23) --412 + j*(-282) --78 + j*(88) --214 + j*(225) --96 + j*(127) --40 + j*(181) -276 + j*(175) --191 + j*(-257) -163 + j*(-84) --82 + j*(92) -171 + j*(132) -213 + j*(-79) -234 + j*(125) --62 + j*(-272) -57 + j*(-56) -62 + j*(-363) --136 + j*(64) -40 + j*(33) --63 + j*(-95) --162 + j*(172) --141 + j*(-281) --13 + j*(40) -248 + j*(-70) --104 + j*(-439) -57 + j*(192) -21 + j*(16) --385 + j*(-86) -86 + j*(-322) --263 + j*(279) -238 + j*(83) -62 + j*(-112) --68 + j*(-26) -30 + j*(182) -6 + j*(-152) -100 + j*(-80) -91 + j*(1) --49 + j*(-240) -88 + j*(19) -74 + j*(98) -87 + j*(234) -5 + j*(-245) --310 + j*(57) --78 + j*(-243) --163 + j*(-32) -114 + j*(-437) -44 + j*(150) -158 + j*(-68) -327 + j*(-263) --3 + j*(-2) -151 + j*(268) --274 + j*(-351) --291 + j*(-420) --409 + j*(204) --454 + j*(-66) -66 + j*(26) --187 + j*(277) -73 + j*(-33) -118 + j*(123) -136 + j*(-40) -87 + j*(138) -264 + j*(47) -93 + j*(288) -113 + j*(107) --233 + j*(95) -19 + j*(170) --23 + j*(-486) -30 + j*(-47) -146 + j*(107) -177 + j*(226) --82 + j*(-301) -155 + j*(58) -78 + j*(-10) -390 + j*(233) --5 + j*(74) --33 + j*(25) --117 + j*(394) -202 + j*(-98) -18 + j*(83) -47 + j*(-127) -230 + j*(-156) -255 + j*(112) --26 + j*(358) -50 + j*(109) --56 + j*(-51) --78 + j*(-240) --190 + j*(42) -119 + j*(98) --146 + j*(84) --37 + j*(-115) -76 + j*(38) -99 + j*(-181) -31 + j*(-63) -69 + j*(61) --100 + j*(62) --81 + j*(161) -130 + j*(-101) -134 + j*(-168) -40 + j*(25) --57 + j*(-278) --58 + j*(244) --368 + j*(-64) -214 + j*(367) -43 + j*(104) -347 + j*(-150) -293 + j*(45) --139 + j*(-16) -198 + j*(120) -286 + j*(255) -342 + j*(-254) -70 + j*(-104) --275 + j*(-223) --37 + j*(-50) --337 + j*(-89) --74 + j*(-56) -133 + j*(202) --61 + j*(255) --209 + j*(-103) --110 + j*(-83) -130 + j*(244) --274 + j*(2) -78 + j*(-186) -56 + j*(163) --122 + j*(-139) -90 + j*(-124) --6 + j*(-28) -99 + j*(-203) --340 + j*(-146) -90 + j*(-62) -215 + j*(-257) -42 + j*(-3) -170 + j*(380) -2 + j*(62) --43 + j*(-52) --331 + j*(12) --26 + j*(33) -77 + j*(141) --184 + j*(-206) -349 + j*(74) -128 + j*(-83) --309 + j*(213) -233 + j*(22) -155 + j*(-16) --82 + j*(-190) --129 + j*(-1) -131 + j*(-341) -182 + j*(-120) -211 + j*(81) -47 + j*(-32) --79 + j*(233) --113 + j*(-443) -89 + j*(170) -218 + j*(-257) --78 + j*(74) --11 + j*(-57) --220 + j*(233) --165 + j*(62) -19 + j*(44) --121 + j*(-240) --3 + j*(-156) -272 + j*(11) --161 + j*(-361) --133 + j*(-153) --51 + j*(122) --30 + j*(56) --116 + j*(-74) -90 + j*(-298) -97 + j*(-151) -126 + j*(-69) -64 + j*(49) --18 + j*(-126) --45 + j*(-190) -72 + j*(-124) -42 + j*(-128) -238 + j*(-228) -18 + j*(-296) -182 + j*(188) -52 + j*(-131) --25 + j*(47) -66 + j*(-49) -327 + j*(-474) -110 + j*(71) --76 + j*(-78) -86 + j*(30) --158 + j*(221) --16 + j*(-371) --144 + j*(100) -9 + j*(197) --65 + j*(-11) --218 + j*(-257) -278 + j*(75) --103 + j*(40) -42 + j*(-145) -496 + j*(53) --161 + j*(-137) --82 + j*(-205) -116 + j*(-37) --134 + j*(98) --26 + j*(392) -221 + j*(-45) --209 + j*(-288) --261 + j*(96) -199 + j*(-429) -516 + j*(-110) -18 + j*(112) -106 + j*(-329) --83 + j*(-117) --190 + j*(36) -177 + j*(252) -13 + j*(15) -0 + j*(-269) -18 + j*(49) -262 + j*(17) --161 + j*(154) -71 + j*(-43) -274 + j*(-88) --167 + j*(67) -192 + j*(-173) --156 + j*(251) --127 + j*(31) -53 + j*(112) --47 + j*(306) --409 + j*(-194) -70 + j*(172) --108 + j*(-223) --54 + j*(6) -215 + j*(283) -281 + j*(-138) -53 + j*(102) -12 + j*(-93) -293 + j*(48) --223 + j*(-163) -37 + j*(127) --21 + j*(-30) -122 + j*(139) --6 + j*(147) --168 + j*(-25) --1 + j*(63) -203 + j*(-30) --184 + j*(-281) -0 + j*(-66) -245 + j*(80) --3 + j*(-154) --151 + j*(-327) --185 + j*(-123) -105 + j*(-202) --218 + j*(190) --54 + j*(29) -25 + j*(-47) --437 + j*(-132) --42 + j*(-11) --264 + j*(-191) --55 + j*(-18) -277 + j*(-223) -69 + j*(-213) --334 + j*(-90) -185 + j*(-269) --95 + j*(-21) --281 + j*(240) --86 + j*(132) --134 + j*(-120) -17 + j*(-402) --30 + j*(-4) -124 + j*(-308) --21 + j*(-54) -107 + j*(-12) -86 + j*(-109) -23 + j*(53) --42 + j*(-352) --68 + j*(-250) -354 + j*(-155) -34 + j*(-111) --156 + j*(228) -127 + j*(-209) -47 + j*(69) --118 + j*(298) -33 + j*(-36) -62 + j*(392) --269 + j*(-88) --366 + j*(-47) --127 + j*(-98) -91 + j*(40) --138 + j*(-253) --57 + j*(181) -186 + j*(-102) -83 + j*(-89) --9 + j*(-419) -109 + j*(265) -124 + j*(316) -12 + j*(-206) --10 + j*(153) --159 + j*(27) -53 + j*(-252) --21 + j*(168) -129 + j*(91) --205 + j*(-82) -85 + j*(143) --11 + j*(17) -71 + j*(-145) -45 + j*(80) -71 + j*(50) -180 + j*(49) -110 + j*(0) --60 + j*(233) -24 + j*(-153) --16 + j*(137) -269 + j*(187) --115 + j*(156) -29 + j*(81) --232 + j*(-161) -206 + j*(-56) --47 + j*(17) --18 + j*(-177) --100 + j*(126) --270 + j*(82) --180 + j*(42) -238 + j*(366) -69 + j*(236) -182 + j*(-151) -0 + j*(180) -232 + j*(-28) -72 + j*(299) -87 + j*(84) -35 + j*(-416) --200 + j*(-43) -206 + j*(-60) --245 + j*(-146) -89 + j*(95) --127 + j*(250) --342 + j*(-6) --5 + j*(342) --239 + j*(-119) -169 + j*(-29) --375 + j*(98) -81 + j*(-380) --65 + j*(4) --139 + j*(-205) -69 + j*(-94) --81 + j*(-175) -16 + j*(-124) --81 + j*(185) -165 + j*(378) --140 + j*(337) -42 + j*(91) --156 + j*(201) --127 + j*(-64) --35 + j*(-177) --238 + j*(-87) --241 + j*(-294) -88 + j*(-289) --164 + j*(56) --141 + j*(-109) -64 + j*(29) --239 + j*(-172) -88 + j*(-416) --188 + j*(-76) --222 + j*(103) -7 + j*(-53) -218 + j*(-284) -82 + j*(-288) -111 + j*(40) --47 + j*(111) --57 + j*(176) -20 + j*(-96) --25 + j*(284) --29 + j*(87) -63 + j*(266) --67 + j*(-129) -154 + j*(-69) -141 + j*(78) -38 + j*(-177) --46 + j*(-306) -271 + j*(125) -378 + j*(130) --303 + j*(-30) -148 + j*(-64) --124 + j*(-332) --153 + j*(71) --49 + j*(18) --78 + j*(-183) --334 + j*(-199) --238 + j*(-58) --269 + j*(-38) -253 + j*(-426) --166 + j*(197) -197 + j*(-147) --33 + j*(-86) -190 + j*(80) --111 + j*(-462) --76 + j*(-369) -501 + j*(-119) -192 + j*(-117) -106 + j*(-60) -148 + j*(-238) -10 + j*(79) -97 + j*(53) -64 + j*(-66) --162 + j*(-535) -60 + j*(83) --188 + j*(-98) -32 + j*(15) --74 + j*(-52) --30 + j*(-102) -61 + j*(300) --64 + j*(8) --245 + j*(105) -114 + j*(-330) -83 + j*(141) -98 + j*(98) --74 + j*(-268) -112 + j*(49) -451 + j*(-61) --107 + j*(52) -136 + j*(-39) --157 + j*(350) -33 + j*(-122) -258 + j*(173) -334 + j*(45) --48 + j*(170) -78 + j*(-82) -59 + j*(-108) -347 + j*(75) --314 + j*(86) --387 + j*(275) -6 + j*(132) --204 + j*(294) -124 + j*(98) --254 + j*(22) --89 + j*(-156) --392 + j*(-168) -141 + j*(-159) -201 + j*(-175) --28 + j*(5) -132 + j*(116) -4 + j*(-4) -227 + j*(-108) --268 + j*(-85) -115 + j*(-98) --57 + j*(139) -200 + j*(-103) --65 + j*(-194) --146 + j*(-59) --314 + j*(45) -146 + j*(-1) -26 + j*(40) --290 + j*(-56) --260 + j*(-264) -165 + j*(35) -235 + j*(-228) -149 + j*(-168) --25 + j*(-196) -33 + j*(-211) --172 + j*(-173) --148 + j*(168) --281 + j*(62) --56 + j*(-12) -179 + j*(-24) -54 + j*(45) --128 + j*(-153) -72 + j*(-62) --12 + j*(343) -214 + j*(-173) --105 + j*(41) -151 + j*(-11) --226 + j*(140) -24 + j*(175) --57 + j*(12) --25 + j*(86) --269 + j*(27) -175 + j*(13) -238 + j*(9) -107 + j*(62) -15 + j*(-73) -115 + j*(-37) -80 + j*(-197) --50 + j*(118) --206 + j*(123) -23 + j*(35) --257 + j*(-112) --66 + j*(183) --155 + j*(-4) --161 + j*(135) -132 + j*(-220) --22 + j*(-358) -197 + j*(277) -339 + j*(8) --232 + j*(-293) -134 + j*(-162) --253 + j*(179) --255 + j*(-197) --110 + j*(-202) --216 + j*(-243) --247 + j*(103) --16 + j*(-33) -107 + j*(-113) --93 + j*(-20) --52 + j*(299) --43 + j*(-234) --131 + j*(-33) -135 + j*(207) -88 + j*(-26) -125 + j*(206) -164 + j*(5) -78 + j*(-178) --151 + j*(-197) -190 + j*(-16) -151 + j*(88) --52 + j*(255) -19 + j*(-182) -144 + j*(-44) --16 + j*(-112) -145 + j*(81) --35 + j*(-1) --107 + j*(-6) -148 + j*(351) --156 + j*(421) --252 + j*(-71) -373 + j*(-182) -228 + j*(51) --71 + j*(137) -83 + j*(201) -54 + j*(-112) -26 + j*(-145) --55 + j*(4) -161 + j*(330) --30 + j*(-250) --421 + j*(-114) -30 + j*(-16) -69 + j*(106) --43 + j*(43) --155 + j*(178) -20 + j*(-208) --395 + j*(226) --147 + j*(129) -11 + j*(-42) --331 + j*(91) -81 + j*(56) --460 + j*(-49) --269 + j*(1) -19 + j*(216) --124 + j*(30) -16 + j*(190) --293 + j*(-240) --170 + j*(149) --101 + j*(95) -130 + j*(-82) --33 + j*(116) -28 + j*(21) -83 + j*(-83) --211 + j*(257) --6 + j*(133) -32 + j*(-163) -44 + j*(-69) -36 + j*(95) --80 + j*(24) --17 + j*(-354) -115 + j*(130) -28 + j*(-41) -287 + j*(195) -433 + j*(-71) --191 + j*(195) --75 + j*(-296) --195 + j*(170) -291 + j*(-35) --164 + j*(128) -271 + j*(50) -132 + j*(-71) -202 + j*(26) -12 + j*(-90) --260 + j*(25) -165 + j*(29) --89 + j*(250) --25 + j*(-21) --33 + j*(-4) -284 + j*(108) --162 + j*(-106) -76 + j*(-163) -85 + j*(70) --106 + j*(61) --273 + j*(32) -24 + j*(-115) -268 + j*(-297) --211 + j*(58) -243 + j*(16) -105 + j*(-155) --36 + j*(-225) -64 + j*(80) --42 + j*(31) -115 + j*(276) --332 + j*(-232) -111 + j*(7) --216 + j*(-134) --154 + j*(-279) --182 + j*(76) -121 + j*(-49) --88 + j*(-52) -167 + j*(-93) --135 + j*(-245) --210 + j*(405) --69 + j*(212) --48 + j*(-240) -385 + j*(306) -31 + j*(108) --7 + j*(-222) -30 + j*(-53) --194 + j*(-183) --21 + j*(57) --330 + j*(171) --42 + j*(-16) -199 + j*(221) --12 + j*(25) --70 + j*(458) --371 + j*(-155) --78 + j*(100) -49 + j*(-85) -110 + j*(-243) --23 + j*(40) -12 + j*(-71) --82 + j*(-624) --156 + j*(53) --153 + j*(264) -2 + j*(-132) -63 + j*(86) -133 + j*(40) -129 + j*(221) -192 + j*(-300) --122 + j*(202) -76 + j*(-155) -94 + j*(28) --17 + j*(281) --382 + j*(105) -310 + j*(158) -20 + j*(122) -211 + j*(-99) -217 + j*(-166) --1 + j*(-130) -32 + j*(-39) --64 + j*(-286) -365 + j*(-83) -216 + j*(89) -167 + j*(-338) -324 + j*(67) -223 + j*(123) -44 + j*(-21) -66 + j*(79) --109 + j*(105) -59 + j*(-62) -211 + j*(35) --165 + j*(-54) -142 + j*(123) --187 + j*(-115) -76 + j*(100) --290 + j*(-316) --78 + j*(162) -156 + j*(49) --69 + j*(-29) -202 + j*(151) -37 + j*(11) --40 + j*(-138) -31 + j*(10) --28 + j*(-112) --195 + j*(175) --178 + j*(187) -51 + j*(-35) -112 + j*(-6) --207 + j*(-35) --70 + j*(19) --129 + j*(-331) -99 + j*(-210) -275 + j*(123) --262 + j*(250) --9 + j*(129) -156 + j*(223) -59 + j*(42) --272 + j*(-320) --107 + j*(-27) --274 + j*(317) --271 + j*(238) -74 + j*(-22) -181 + j*(-249) -286 + j*(86) -57 + j*(268) --69 + j*(-50) -22 + j*(233) -137 + j*(168) -156 + j*(88) -250 + j*(165) -175 + j*(-258) --250 + j*(-158) --57 + j*(251) --192 + j*(98) -88 + j*(208) --175 + j*(130) -40 + j*(-162) --237 + j*(-4) -272 + j*(8) --54 + j*(163) -105 + j*(72) -216 + j*(-69) --257 + j*(139) --250 + j*(53) -30 + j*(-439) -78 + j*(-208) -182 + j*(177) -262 + j*(83) -318 + j*(-4) --6 + j*(214) --37 + j*(-172) --144 + j*(-33) --278 + j*(42) -195 + j*(29) -158 + j*(76) --30 + j*(-395) -189 + j*(-122) --165 + j*(-22) --307 + j*(240) -18 + j*(-73) -11 + j*(422) --108 + j*(-59) -366 + j*(13) --81 + j*(-116) --286 + j*(244) -99 + j*(349) --102 + j*(-100) --247 + j*(-32) -2 + j*(175) --40 + j*(337) -284 + j*(124) -107 + j*(-8) -126 + j*(107) --348 + j*(-184) -206 + j*(-15) -242 + j*(-8) -248 + j*(9) -83 + j*(65) --153 + j*(53) --117 + j*(169) --359 + j*(41) --34 + j*(3) --264 + j*(-237) -42 + j*(-223) -218 + j*(116) --92 + j*(-192) --259 + j*(-144) -304 + j*(78) --10 + j*(337) -8 + j*(122) --57 + j*(28) --35 + j*(37) --46 + j*(13) -55 + j*(261) --244 + j*(-163) -42 + j*(-45) --339 + j*(-79) -82 + j*(412) -7 + j*(150) -132 + j*(199) -137 + j*(-323) -269 + j*(-166) --7 + j*(54) --243 + j*(232) --180 + j*(-30) --78 + j*(-49) --113 + j*(4) -30 + j*(-32) -95 + j*(64) --1 + j*(-146) -20 + j*(-11) -91 + j*(194) -51 + j*(-269) --250 + j*(-105) --141 + j*(-33) --114 + j*(310) -177 + j*(211) --138 + j*(417) --13 + j*(258) -260 + j*(-113) -47 + j*(169) -11 + j*(-429) --204 + j*(-11) --370 + j*(33) -401 + j*(-77) -74 + j*(186) -322 + j*(146) -57 + j*(-364) -18 + j*(-114) -171 + j*(-362) --86 + j*(66) -11 + j*(-148) --72 + j*(190) -185 + j*(-168) --73 + j*(-161) -182 + j*(18) --256 + j*(-304) --103 + j*(21) --41 + j*(358) --136 + j*(132) --18 + j*(-144) -267 + j*(102) -76 + j*(146) --5 + j*(-34) --105 + j*(29) --261 + j*(-179) --86 + j*(63) -106 + j*(280) --15 + j*(-155) -144 + j*(-52) --55 + j*(-344) -156 + j*(-20) -161 + j*(-242) -163 + j*(-223) --354 + j*(64) --5 + j*(-21) -20 + j*(-246) -210 + j*(-316) -396 + j*(-194) -16 + j*(225) --228 + j*(165) -46 + j*(21) --43 + j*(-298) --129 + j*(-132) --201 + j*(77) --32 + j*(21) --37 + j*(107) --16 + j*(94) -18 + j*(-93) -207 + j*(-175) -88 + j*(226) -216 + j*(-142) --170 + j*(102) -21 + j*(-291) -119 + j*(-173) --236 + j*(-33) -49 + j*(302) --151 + j*(136) --284 + j*(-181) -286 + j*(39) --70 + j*(160) --56 + j*(122) -5 + j*(320) --34 + j*(-181) --272 + j*(83) -33 + j*(-203) --248 + j*(-199) -146 + j*(255) --190 + j*(28) --60 + j*(-340) -13 + j*(-252) -134 + j*(269) -130 + j*(-115) -137 + j*(-25) -292 + j*(141) -171 + j*(82) -14 + j*(49) -11 + j*(23) --257 + j*(124) --130 + j*(-160) --247 + j*(164) --13 + j*(168) --62 + j*(-258) --11 + j*(-66) -291 + j*(274) -42 + j*(224) --135 + j*(266) --109 + j*(47) --37 + j*(-110) -84 + j*(-120) --73 + j*(322) --52 + j*(33) --139 + j*(24) -42 + j*(-132) -41 + j*(259) --45 + j*(165) -248 + j*(-201) --334 + j*(-131) --92 + j*(154) -202 + j*(7) -88 + j*(154) --100 + j*(42) --251 + j*(9) -129 + j*(-116) --187 + j*(82) -134 + j*(-412) --271 + j*(-181) --137 + j*(-20) --57 + j*(79) -136 + j*(95) -81 + j*(157) --100 + j*(107) --235 + j*(233) -117 + j*(-72) -388 + j*(-156) --147 + j*(-264) -0 + j*(-124) --18 + j*(156) --119 + j*(-114) --334 + j*(144) -206 + j*(303) -181 + j*(84) --198 + j*(-121) --146 + j*(91) --49 + j*(-77) -313 + j*(148) --241 + j*(57) -33 + j*(11) -161 + j*(-20) --76 + j*(158) -51 + j*(28) --106 + j*(67) --6 + j*(-136) --172 + j*(-97) -77 + j*(112) -0 + j*(59) -34 + j*(-29) -276 + j*(-67) --209 + j*(-214) -21 + j*(-59) -19 + j*(23) -35 + j*(-177) --221 + j*(242) -49 + j*(-40) -291 + j*(248) -220 + j*(57) --193 + j*(65) -129 + j*(101) --36 + j*(-160) --431 + j*(-53) --78 + j*(-492) -147 + j*(-326) --260 + j*(-37) -322 + j*(-134) --202 + j*(-203) -58 + j*(40) -45 + j*(-83) --66 + j*(-205) --130 + j*(-68) -122 + j*(47) -124 + j*(-115) --37 + j*(281) --276 + j*(-77) --188 + j*(379) -195 + j*(-42) --4 + j*(110) --288 + j*(-63) -1 + j*(-96) -69 + j*(-42) -100 + j*(173) --129 + j*(246) -311 + j*(-30) --71 + j*(-151) --368 + j*(-41) --347 + j*(190) --173 + j*(-92) --170 + j*(224) --40 + j*(-163) --103 + j*(90) -373 + j*(301) --206 + j*(55) --8 + j*(-184) -30 + j*(-18) --184 + j*(15) --132 + j*(103) -69 + j*(88) --115 + j*(-293) --318 + j*(124) -250 + j*(284) -33 + j*(-127) -193 + j*(317) --72 + j*(242) --32 + j*(122) --214 + j*(277) -78 + j*(-18) --173 + j*(-41) --135 + j*(-180) --31 + j*(-104) --22 + j*(278) -52 + j*(-16) -204 + j*(-62) --30 + j*(-24) -171 + j*(-48) --54 + j*(-339) --84 + j*(91) --95 + j*(-288) -40 + j*(-330) --115 + j*(16) --451 + j*(-48) -119 + j*(99) --36 + j*(135) -200 + j*(144) -127 + j*(-43) -252 + j*(91) -105 + j*(218) -29 + j*(176) -139 + j*(-190) --108 + j*(-139) -144 + j*(-76) -120 + j*(214) -47 + j*(228) --42 + j*(-4) -279 + j*(3) --140 + j*(-100) --16 + j*(49) --148 + j*(-21) -102 + j*(-150) --48 + j*(-264) --204 + j*(-53) -207 + j*(81) --272 + j*(-115) --28 + j*(-252) --61 + j*(-4) --114 + j*(116) -64 + j*(182) -131 + j*(101) -117 + j*(-1) -148 + j*(-296) -99 + j*(248) -112 + j*(-18) -198 + j*(306) --63 + j*(13) --226 + j*(-149) -93 + j*(121) --233 + j*(140) --156 + j*(-279) --182 + j*(-107) --117 + j*(-240) --209 + j*(36) -32 + j*(-31) -257 + j*(-126) --320 + j*(94) -25 + j*(-454) --35 + j*(81) --132 + j*(170) --161 + j*(230) -365 + j*(304) --53 + j*(-175) -101 + j*(165) -242 + j*(301) -113 + j*(190) -164 + j*(-160) -25 + j*(-512) -343 + j*(31) --228 + j*(4) -185 + j*(-76) --13 + j*(272) -69 + j*(6) -45 + j*(-23) -3 + j*(135) --240 + j*(-105) -124 + j*(143) --40 + j*(-218) --35 + j*(-109) --23 + j*(-3) --96 + j*(-139) -93 + j*(240) --193 + j*(-181) --45 + j*(80) -165 + j*(-144) --176 + j*(-94) --85 + j*(-242) --100 + j*(-11) --73 + j*(181) --6 + j*(-151) -98 + j*(109) --223 + j*(101) --279 + j*(58) -81 + j*(86) -14 + j*(102) -56 + j*(-215) --228 + j*(-92) --165 + j*(-62) -262 + j*(52) --40 + j*(-160) --183 + j*(-139) -226 + j*(-66) --107 + j*(184) -115 + j*(-64) --129 + j*(139) -90 + j*(-296) --88 + j*(-1) --81 + j*(-83) -78 + j*(-35) -68 + j*(-37) --86 + j*(-149) --1 + j*(84) --124 + j*(-24) --319 + j*(-315) --105 + j*(-221) --185 + j*(77) --211 + j*(28) --58 + j*(-169) -59 + j*(-424) -97 + j*(222) --82 + j*(216) -170 + j*(-109) -185 + j*(6) --328 + j*(202) --128 + j*(-71) --34 + j*(-259) -23 + j*(409) --218 + j*(55) -55 + j*(-269) --49 + j*(368) -62 + j*(131) -15 + j*(29) -79 + j*(349) -9 + j*(-190) --188 + j*(232) -194 + j*(153) -74 + j*(291) --152 + j*(119) -148 + j*(-206) --110 + j*(-170) -194 + j*(-139) -113 + j*(-100) --209 + j*(-302) -2 + j*(64) --128 + j*(-59) -13 + j*(-122) -7 + j*(-200) -25 + j*(-101) -104 + j*(-127) -168 + j*(-125) -93 + j*(-216) --91 + j*(-49) --179 + j*(-68) --95 + j*(117) -267 + j*(-81) --48 + j*(-41) --122 + j*(-340) --91 + j*(216) -104 + j*(142) --69 + j*(-206) --82 + j*(-101) --93 + j*(136) -6 + j*(-57) --51 + j*(-202) -53 + j*(-167) --127 + j*(-216) --292 + j*(-243) -170 + j*(-228) --241 + j*(-90) --132 + j*(-216) --81 + j*(-295) --40 + j*(96) --180 + j*(-167) --404 + j*(42) --64 + j*(-373) --190 + j*(100) -75 + j*(-219) -430 + j*(219) --23 + j*(-146) --93 + j*(25) -18 + j*(257) --28 + j*(303) --209 + j*(261) -748 + j*(271) -177 + j*(154) -352 + j*(577) --202 + j*(-223) --177 + j*(11) -327 + j*(256) -346 + j*(-228) --372 + j*(398) -354 + j*(666) -399 + j*(-1) -406 + j*(-42) -105 + j*(-37) --281 + j*(523) --76 + j*(-529) -675 + j*(81) --245 + j*(418) -333 + j*(275) --395 + j*(136) --63 + j*(338) --166 + j*(-158) --139 + j*(-445) --238 + j*(407) --342 + j*(-115) --323 + j*(101) --547 + j*(289) -329 + j*(117) --255 + j*(-172) -375 + j*(-109) --52 + j*(-234) -643 + j*(-313) --18 + j*(258) -11 + j*(168) --12 + j*(15) -351 + j*(-247) --199 + j*(334) -387 + j*(21) --126 + j*(63) --375 + j*(263) -23 + j*(206) -31 + j*(261) --211 + j*(334) -633 + j*(210) --194 + j*(-467) -335 + j*(-243) -368 + j*(-135) -542 + j*(-241) --190 + j*(-300) --18 + j*(-262) -279 + j*(-42) --548 + j*(-407) -107 + j*(-480) -318 + j*(274) --220 + j*(-252) -142 + j*(66) --156 + j*(290) --474 + j*(320) -602 + j*(255) --226 + j*(187) --403 + j*(-288) --443 + j*(-303) -159 + j*(-513) --480 + j*(-58) -263 + j*(-127) --346 + j*(537) -187 + j*(-350) --146 + j*(336) --175 + j*(-127) -250 + j*(532) -317 + j*(173) --38 + j*(-279) -339 + j*(-542) -168 + j*(-103) -606 + j*(-121) -128 + j*(-260) -132 + j*(-116) -487 + j*(497) --177 + j*(-310) --281 + j*(-375) --33 + j*(-250) --459 + j*(37) -13 + j*(-3) -206 + j*(-288) -167 + j*(-218) -225 + j*(163) --460 + j*(-350) --422 + j*(-256) --273 + j*(-288) -145 + j*(-539) -264 + j*(675) --177 + j*(-416) --278 + j*(92) -256 + j*(93) --11 + j*(122) -119 + j*(205) -264 + j*(-350) -267 + j*(320) -628 + j*(115) --300 + j*(206) --256 + j*(127) -46 + j*(644) --257 + j*(174) -397 + j*(-358) -437 + j*(-221) --404 + j*(-392) --453 + j*(-234) -211 + j*(-168) --473 + j*(-173) -378 + j*(297) -206 + j*(280) --203 + j*(-341) --251 + j*(-229) -173 + j*(-60) --311 + j*(-156) -1 + j*(134) --24 + j*(-322) --291 + j*(-203) --424 + j*(127) -134 + j*(-62) --295 + j*(-141) --380 + j*(-233) --83 + j*(320) --169 + j*(171) --419 + j*(263) -219 + j*(-126) --227 + j*(221) --533 + j*(-33) -139 + j*(162) --259 + j*(81) --77 + j*(-316) --334 + j*(368) -78 + j*(-279) --127 + j*(-14) -186 + j*(-54) --317 + j*(-562) -127 + j*(424) -23 + j*(241) --170 + j*(-218) -533 + j*(511) --530 + j*(-110) --246 + j*(576) -151 + j*(-443) -38 + j*(358) --462 + j*(-40) --293 + j*(386) -403 + j*(404) -465 + j*(126) --39 + j*(220) -546 + j*(-482) -187 + j*(267) --166 + j*(-417) -293 + j*(-158) -190 + j*(-276) -291 + j*(-456) --256 + j*(177) -236 + j*(83) --21 + j*(566) --309 + j*(-536) --276 + j*(274) -291 + j*(30) -316 + j*(480) -471 + j*(114) --284 + j*(197) -344 + j*(-291) --263 + j*(-347) -81 + j*(33) --381 + j*(-364) -49 + j*(-97) -300 + j*(516) -303 + j*(-48) -192 + j*(499) -115 + j*(-372) -387 + j*(-398) -264 + j*(2) --104 + j*(286) -643 + j*(-144) -327 + j*(447) -33 + j*(-457) --221 + j*(-59) --251 + j*(37) -300 + j*(4) -245 + j*(77) --199 + j*(-344) --103 + j*(16) --275 + j*(596) -226 + j*(-307) --321 + j*(379) -151 + j*(237) -403 + j*(-258) -292 + j*(-358) -728 + j*(378) -204 + j*(601) --392 + j*(-49) -205 + j*(56) --96 + j*(143) --361 + j*(270) -132 + j*(159) -342 + j*(156) -171 + j*(262) -252 + j*(55) -205 + j*(-261) -272 + j*(-192) -225 + j*(139) --375 + j*(241) --179 + j*(325) --121 + j*(-150) -178 + j*(-279) -532 + j*(-95) --397 + j*(361) -149 + j*(-227) --253 + j*(-415) --622 + j*(-208) --309 + j*(369) -305 + j*(361) -224 + j*(394) -385 + j*(617) --238 + j*(-120) -524 + j*(-277) --209 + j*(-190) -387 + j*(658) -405 + j*(211) -45 + j*(333) --313 + j*(137) --313 + j*(-31) -492 + j*(320) -138 + j*(-307) --240 + j*(364) -316 + j*(204) -177 + j*(-408) -204 + j*(-63) -358 + j*(-165) --47 + j*(-238) -425 + j*(361) -596 + j*(-56) -409 + j*(-180) --61 + j*(-536) --389 + j*(262) --337 + j*(-270) --185 + j*(-47) --414 + j*(-222) -394 + j*(200) -102 + j*(201) --581 + j*(-57) -312 + j*(118) -284 + j*(421) -171 + j*(242) -385 + j*(-218) -119 + j*(166) -408 + j*(484) -215 + j*(188) -269 + j*(434) -8 + j*(337) --308 + j*(514) -366 + j*(-49) -167 + j*(-166) -638 + j*(185) -344 + j*(-203) --331 + j*(174) -315 + j*(-16) -264 + j*(-185) --389 + j*(382) --76 + j*(-346) -284 + j*(221) -216 + j*(309) --296 + j*(-339) --290 + j*(89) -341 + j*(400) -126 + j*(-108) -267 + j*(288) --211 + j*(177) -355 + j*(-21) -522 + j*(255) -268 + j*(-234) -436 + j*(392) -703 + j*(57) --435 + j*(-436) -284 + j*(-130) --115 + j*(-286) --614 + j*(-284) --152 + j*(-368) -219 + j*(-30) -313 + j*(-261) --134 + j*(-260) --55 + j*(-498) --254 + j*(291) -196 + j*(-122) -318 + j*(334) --264 + j*(366) -13 + j*(-230) -314 + j*(609) -241 + j*(-139) --88 + j*(347) -323 + j*(-305) --443 + j*(-257) --231 + j*(300) --424 + j*(479) -320 + j*(543) -23 + j*(-188) --392 + j*(22) --497 + j*(93) --218 + j*(-392) --286 + j*(-441) --263 + j*(-591) --153 + j*(-87) --125 + j*(204) --385 + j*(54) -92 + j*(269) --45 + j*(46) --571 + j*(-607) --372 + j*(122) --384 + j*(19) -193 + j*(258) --22 + j*(377) --268 + j*(331) --184 + j*(425) -554 + j*(-243) --146 + j*(490) --168 + j*(-530) -180 + j*(38) --352 + j*(25) --334 + j*(57) --215 + j*(188) -57 + j*(89) -196 + j*(182) -397 + j*(491) --361 + j*(-99) -214 + j*(161) --84 + j*(346) -112 + j*(364) --244 + j*(346) --320 + j*(79) -406 + j*(93) --196 + j*(-371) -158 + j*(-298) -82 + j*(189) --342 + j*(-235) -202 + j*(-280) --194 + j*(-349) --197 + j*(-312) --291 + j*(-99) --171 + j*(283) -87 + j*(-41) --266 + j*(92) -595 + j*(573) --362 + j*(-139) -154 + j*(-235) -127 + j*(-603) -191 + j*(663) -387 + j*(-70) -275 + j*(505) -161 + j*(-393) -411 + j*(-243) --258 + j*(366) --273 + j*(35) --436 + j*(-470) -472 + j*(62) --401 + j*(75) -99 + j*(-165) -180 + j*(421) -270 + j*(-199) --52 + j*(-218) --260 + j*(-283) --527 + j*(277) --286 + j*(456) --444 + j*(97) --276 + j*(309) -132 + j*(-304) --231 + j*(-378) --245 + j*(153) -406 + j*(305) --338 + j*(229) -163 + j*(180) --281 + j*(290) -477 + j*(-118) --377 + j*(457) -169 + j*(-161) --347 + j*(-248) -291 + j*(-45) --157 + j*(60) -124 + j*(227) --281 + j*(-433) -513 + j*(-282) -333 + j*(235) -299 + j*(-273) -322 + j*(211) -391 + j*(402) -198 + j*(-60) --58 + j*(-472) -559 + j*(125) -130 + j*(334) --93 + j*(245) -471 + j*(-211) -93 + j*(276) -36 + j*(-378) -780 + j*(281) --291 + j*(301) -286 + j*(334) -227 + j*(-363) -351 + j*(163) -194 + j*(98) --512 + j*(317) --47 + j*(197) --325 + j*(393) -122 + j*(9) --264 + j*(-231) -339 + j*(141) --274 + j*(-426) -330 + j*(-318) -625 + j*(-276) --372 + j*(406) --253 + j*(-171) --314 + j*(-271) -159 + j*(161) -264 + j*(-505) --280 + j*(563) -326 + j*(3) -235 + j*(78) -66 + j*(-384) -368 + j*(156) --227 + j*(-17) --409 + j*(-381) --252 + j*(-306) -108 + j*(218) --433 + j*(-35) -16 + j*(23) -648 + j*(-353) -296 + j*(47) --291 + j*(360) -408 + j*(-459) -530 + j*(156) -175 + j*(262) -8 + j*(-363) -57 + j*(221) -142 + j*(161) --162 + j*(72) -185 + j*(-160) -280 + j*(-128) --272 + j*(-232) -31 + j*(-88) --626 + j*(-132) -122 + j*(-325) --274 + j*(126) --312 + j*(206) -231 + j*(37) --261 + j*(-124) -86 + j*(450) --328 + j*(-586) --175 + j*(-283) -25 + j*(-170) -340 + j*(372) -385 + j*(181) -354 + j*(-480) --204 + j*(30) --368 + j*(273) --315 + j*(204) --453 + j*(269) --433 + j*(173) -532 + j*(258) -351 + j*(-124) --26 + j*(-1) -208 + j*(83) -84 + j*(141) --620 + j*(-32) --229 + j*(34) --146 + j*(-315) --143 + j*(-223) --135 + j*(375) -421 + j*(345) -498 + j*(-307) -425 + j*(-670) -315 + j*(613) --361 + j*(253) -470 + j*(-390) --8 + j*(132) --173 + j*(74) --375 + j*(317) -278 + j*(-225) --247 + j*(156) --371 + j*(-346) --366 + j*(-146) -417 + j*(-374) -27 + j*(-231) -462 + j*(311) --147 + j*(385) -433 + j*(-363) --347 + j*(-521) --345 + j*(206) --503 + j*(473) -238 + j*(-395) -159 + j*(-239) --163 + j*(189) --468 + j*(-154) --351 + j*(-30) --271 + j*(491) -277 + j*(94) --4 + j*(-162) -331 + j*(-389) --246 + j*(496) -165 + j*(330) -453 + j*(257) --64 + j*(-125) --544 + j*(-247) -135 + j*(-176) --383 + j*(-524) --16 + j*(693) --104 + j*(189) -139 + j*(110) -525 + j*(236) -172 + j*(-342) -313 + j*(223) -307 + j*(-435) --525 + j*(-231) -317 + j*(-317) --525 + j*(-696) -245 + j*(-131) --568 + j*(-351) -71 + j*(-274) --57 + j*(95) --313 + j*(-417) -250 + j*(-74) -338 + j*(-238) -270 + j*(-151) --166 + j*(437) --414 + j*(460) --285 + j*(304) --274 + j*(511) -408 + j*(-422) -25 + j*(-37) --370 + j*(107) -367 + j*(146) --135 + j*(-324) --329 + j*(180) -163 + j*(-82) --568 + j*(185) --496 + j*(-288) --416 + j*(-366) -37 + j*(-95) -70 + j*(-424) -88 + j*(38) --277 + j*(87) --44 + j*(404) --184 + j*(-651) --304 + j*(-487) --301 + j*(-136) --36 + j*(-501) -416 + j*(104) -130 + j*(-443) -127 + j*(-177) -387 + j*(-144) --186 + j*(6) --333 + j*(-57) --101 + j*(-190) -450 + j*(161) -85 + j*(-147) -442 + j*(-466) --52 + j*(-173) -45 + j*(13) -289 + j*(96) -148 + j*(461) --49 + j*(330) --6 + j*(-279) --44 + j*(152) -279 + j*(-176) -404 + j*(178) -239 + j*(297) --267 + j*(449) --371 + j*(-45) --206 + j*(-267) -144 + j*(-57) --352 + j*(199) -249 + j*(472) --87 + j*(136) --147 + j*(-480) -442 + j*(397) --30 + j*(129) --322 + j*(417) -818 + j*(11) --14 + j*(338) --257 + j*(-72) -352 + j*(-235) --411 + j*(82) -348 + j*(-66) -50 + j*(257) --315 + j*(103) --394 + j*(-30) --274 + j*(336) --436 + j*(-178) --147 + j*(-202) -173 + j*(264) --167 + j*(-347) --430 + j*(-67) -229 + j*(-447) --255 + j*(771) -29 + j*(-579) -412 + j*(208) -385 + j*(-573) --523 + j*(-310) --513 + j*(-223) -148 + j*(-237) --70 + j*(127) --346 + j*(12) --245 + j*(-208) --146 + j*(204) --216 + j*(23) -4 + j*(87) --163 + j*(274) --146 + j*(-27) --74 + j*(250) --97 + j*(69) -18 + j*(85) --33 + j*(-192) --84 + j*(-299) -15 + j*(32) -182 + j*(-194) -30 + j*(-209) --151 + j*(-126) -315 + j*(-103) --146 + j*(-21) -79 + j*(168) -535 + j*(44) -169 + j*(-331) --139 + j*(229) --192 + j*(55) --84 + j*(-47) -221 + j*(78) --83 + j*(-228) -86 + j*(-13) --165 + j*(58) --315 + j*(72) --57 + j*(-23) -16 + j*(-209) --50 + j*(-103) --206 + j*(-19) -36 + j*(-36) --78 + j*(-187) --224 + j*(173) -172 + j*(29) -284 + j*(66) -155 + j*(194) -14 + j*(28) -144 + j*(-105) --102 + j*(-113) --132 + j*(-83) -15 + j*(-325) -40 + j*(-86) -203 + j*(-185) -64 + j*(115) -427 + j*(-47) -20 + j*(40) --71 + j*(127) -238 + j*(44) -112 + j*(-142) -39 + j*(-171) -122 + j*(-204) -62 + j*(-64) --33 + j*(-149) --170 + j*(106) -296 + j*(52) -332 + j*(279) -203 + j*(70) -286 + j*(76) --206 + j*(42) --11 + j*(298) -129 + j*(-209) -110 + j*(218) --17 + j*(-75) -198 + j*(15) -153 + j*(256) --6 + j*(-125) -71 + j*(-89) -64 + j*(-11) -80 + j*(-31) -192 + j*(112) --196 + j*(-18) --21 + j*(204) --54 + j*(305) -10 + j*(292) -30 + j*(238) --144 + j*(333) --230 + j*(-60) --354 + j*(76) -87 + j*(-45) -193 + j*(215) --170 + j*(204) -143 + j*(93) --206 + j*(231) -151 + j*(121) -323 + j*(-74) --132 + j*(-209) --150 + j*(-150) --153 + j*(-82) --243 + j*(-144) -310 + j*(95) -342 + j*(-61) --155 + j*(-117) -357 + j*(66) --360 + j*(119) -86 + j*(-33) -209 + j*(40) --105 + j*(62) -163 + j*(43) --58 + j*(56) -134 + j*(-247) -14 + j*(84) --105 + j*(-28) --193 + j*(-215) --51 + j*(-180) -97 + j*(-98) --116 + j*(-25) -422 + j*(107) -105 + j*(62) --30 + j*(62) -255 + j*(141) --247 + j*(240) -23 + j*(25) --163 + j*(6) -0 + j*(308) --115 + j*(-250) --83 + j*(-33) --345 + j*(-57) -495 + j*(-29) -148 + j*(-51) --203 + j*(144) --57 + j*(39) --52 + j*(283) --7 + j*(218) -300 + j*(-182) -274 + j*(202) -59 + j*(13) --74 + j*(259) -300 + j*(28) -1 + j*(117) -151 + j*(242) -267 + j*(332) -57 + j*(-315) -38 + j*(-178) -65 + j*(8) --144 + j*(-271) -213 + j*(-199) -151 + j*(-91) --252 + j*(-130) --93 + j*(-66) -74 + j*(69) --118 + j*(110) -293 + j*(187) -124 + j*(84) -211 + j*(-75) --40 + j*(-15) -123 + j*(28) -105 + j*(-295) -198 + j*(185) -76 + j*(74) --236 + j*(203) --81 + j*(1) --135 + j*(73) --333 + j*(-332) -46 + j*(64) --37 + j*(233) --17 + j*(37) -321 + j*(182) -146 + j*(307) -98 + j*(-2) --191 + j*(-138) --252 + j*(124) -168 + j*(-105) -28 + j*(343) --59 + j*(-71) --119 + j*(-351) -18 + j*(-82) -319 + j*(69) -140 + j*(-41) -278 + j*(301) --142 + j*(166) --189 + j*(-316) -173 + j*(-260) --26 + j*(-151) --94 + j*(-54) -10 + j*(23) -134 + j*(-170) --45 + j*(-260) -138 + j*(-59) -79 + j*(-220) -2 + j*(102) -163 + j*(74) --105 + j*(42) --295 + j*(-200) -184 + j*(-141) --216 + j*(246) --66 + j*(-23) -185 + j*(86) --378 + j*(146) --137 + j*(250) -233 + j*(190) --66 + j*(-220) --30 + j*(-128) -332 + j*(-71) -293 + j*(-6) --35 + j*(-1) --58 + j*(247) -252 + j*(-73) --75 + j*(-220) --57 + j*(6) --197 + j*(-8) -321 + j*(149) --308 + j*(141) -146 + j*(-230) --168 + j*(-322) --315 + j*(-190) -120 + j*(-298) -155 + j*(-344) --15 + j*(146) --156 + j*(-192) --91 + j*(-6) --62 + j*(-40) --40 + j*(109) --256 + j*(-19) -118 + j*(-350) --365 + j*(-211) --68 + j*(-100) --86 + j*(-320) -33 + j*(-34) -136 + j*(1) -7 + j*(430) -161 + j*(54) -30 + j*(-78) --87 + j*(-162) -282 + j*(269) --277 + j*(260) --10 + j*(404) -245 + j*(134) --96 + j*(-129) --183 + j*(83) --114 + j*(266) --3 + j*(-74) -115 + j*(77) -141 + j*(31) --105 + j*(50) --20 + j*(-341) -148 + j*(-116) -388 + j*(-106) --112 + j*(-20) -58 + j*(-6) -207 + j*(-138) -124 + j*(-84) --174 + j*(71) --79 + j*(321) --153 + j*(48) --171 + j*(-315) --115 + j*(19) --73 + j*(-77) --2 + j*(-59) -71 + j*(-69) -13 + j*(1) -129 + j*(-286) --316 + j*(162) -303 + j*(210) -32 + j*(136) --199 + j*(85) --248 + j*(169) -246 + j*(88) -309 + j*(-105) -83 + j*(-149) --46 + j*(-25) --194 + j*(-202) --88 + j*(-108) -76 + j*(29) -79 + j*(-213) --90 + j*(14) --88 + j*(106) --194 + j*(-71) --57 + j*(42) --478 + j*(-83) -269 + j*(-33) -180 + j*(25) --47 + j*(-96) --190 + j*(115) --10 + j*(-342) --144 + j*(-26) --264 + j*(4) --192 + j*(48) --303 + j*(117) --49 + j*(268) -95 + j*(-177) -419 + j*(69) --131 + j*(156) --170 + j*(-4) --8 + j*(-139) --42 + j*(185) -0 + j*(-301) -20 + j*(-200) -397 + j*(-147) --130 + j*(-238) --42 + j*(33) --78 + j*(12) --59 + j*(-111) --206 + j*(-145) --141 + j*(-148) --94 + j*(-163) -146 + j*(-16) -43 + j*(211) -202 + j*(244) --67 + j*(-282) -223 + j*(64) -65 + j*(194) --76 + j*(-1) -14 + j*(240) --51 + j*(136) --23 + j*(165) --44 + j*(64) -110 + j*(132) --153 + j*(-107) --20 + j*(-114) --226 + j*(-141) --103 + j*(4) --113 + j*(211) -153 + j*(-9) -252 + j*(-18) --115 + j*(-216) --83 + j*(295) -165 + j*(47) -66 + j*(-152) -194 + j*(88) --46 + j*(-30) -100 + j*(-37) -148 + j*(-224) -167 + j*(84) --174 + j*(-62) --333 + j*(-233) -250 + j*(-173) -325 + j*(-9) -36 + j*(-29) --85 + j*(20) -141 + j*(179) --13 + j*(15) --179 + j*(-415) --358 + j*(87) --236 + j*(236) -291 + j*(-188) --114 + j*(268) --187 + j*(-233) -62 + j*(-151) --139 + j*(-336) -301 + j*(-37) --75 + j*(74) -12 + j*(-259) --351 + j*(-17) -193 + j*(-151) --4 + j*(105) -206 + j*(5) --153 + j*(-107) -185 + j*(242) --5 + j*(-105) -20 + j*(14) -36 + j*(368) -37 + j*(139) -11 + j*(-123) --218 + j*(-71) --122 + j*(86) --95 + j*(95) --412 + j*(-148) --218 + j*(-69) --326 + j*(-87) --131 + j*(11) --11 + j*(84) -98 + j*(-194) --49 + j*(-99) -207 + j*(-170) --200 + j*(-292) --46 + j*(152) --144 + j*(-54) -196 + j*(268) -100 + j*(31) --132 + j*(157) --95 + j*(-239) -185 + j*(-6) --117 + j*(-161) -106 + j*(164) -122 + j*(48) --47 + j*(45) -47 + j*(83) -195 + j*(361) -68 + j*(207) -43 + j*(17) --120 + j*(-76) -1 + j*(-81) --138 + j*(-8) -1 + j*(-15) -10 + j*(-10) -30 + j*(37) --24 + j*(-55) --235 + j*(251) --16 + j*(236) -139 + j*(-286) -62 + j*(86) -183 + j*(-165) --71 + j*(-117) -57 + j*(-56) -71 + j*(-23) --518 + j*(52) -189 + j*(-45) -3 + j*(-190) -89 + j*(186) -36 + j*(-11) --308 + j*(283) -153 + j*(-55) -170 + j*(68) -16 + j*(-214) -141 + j*(223) -13 + j*(163) --99 + j*(197) --350 + j*(-84) -361 + j*(-123) --153 + j*(-35) -184 + j*(-101) --250 + j*(104) --256 + j*(147) --56 + j*(166) --67 + j*(-78) -1 + j*(-257) --173 + j*(-69) --109 + j*(-93) --17 + j*(71) -243 + j*(-110) -54 + j*(166) --80 + j*(-250) --134 + j*(-32) --169 + j*(-201) --98 + j*(-239) -339 + j*(-90) --11 + j*(-78) -25 + j*(45) -109 + j*(-8) -45 + j*(-274) --215 + j*(-130) --139 + j*(178) -213 + j*(-269) --202 + j*(-202) --221 + j*(-17) -219 + j*(-466) -87 + j*(-278) -358 + j*(-91) -5 + j*(169) --129 + j*(330) -42 + j*(0) --86 + j*(-29) --80 + j*(295) --154 + j*(-121) -76 + j*(233) -238 + j*(-31) -97 + j*(-160) -23 + j*(-81) -5 + j*(-187) --39 + j*(-139) --262 + j*(83) -128 + j*(23) --274 + j*(-51) -229 + j*(-56) -127 + j*(486) -104 + j*(112) --46 + j*(257) --210 + j*(-244) -81 + j*(111) -112 + j*(198) -231 + j*(319) --86 + j*(103) --7 + j*(-55) --6 + j*(-153) -139 + j*(141) -37 + j*(212) -56 + j*(346) -298 + j*(-73) --4 + j*(-55) -163 + j*(36) --46 + j*(229) -124 + j*(-144) --156 + j*(122) --209 + j*(-109) -117 + j*(-151) --235 + j*(-193) --38 + j*(-64) -136 + j*(28) -66 + j*(-388) --102 + j*(101) -171 + j*(182) --192 + j*(81) -251 + j*(-343) -261 + j*(-61) -88 + j*(-33) --158 + j*(408) -305 + j*(-63) --8 + j*(-103) -565 + j*(250) --128 + j*(-51) --211 + j*(-122) --115 + j*(170) -42 + j*(-29) --99 + j*(-112) --30 + j*(-85) -232 + j*(213) -282 + j*(-5) --86 + j*(113) --300 + j*(-236) --132 + j*(-146) --4 + j*(93) -99 + j*(215) --70 + j*(-24) --95 + j*(23) --104 + j*(-33) -237 + j*(-209) -190 + j*(-75) -15 + j*(73) -106 + j*(86) -3 + j*(-178) -148 + j*(-86) -105 + j*(209) -34 + j*(-276) -10 + j*(204) -135 + j*(-187) --57 + j*(-210) -69 + j*(93) --7 + j*(487) --141 + j*(-340) -33 + j*(13) -106 + j*(-265) -51 + j*(105) --247 + j*(-185) --168 + j*(-27) --46 + j*(-325) -79 + j*(139) --74 + j*(535) -245 + j*(-96) -334 + j*(-317) --103 + j*(159) --204 + j*(-19) -144 + j*(239) -36 + j*(-187) -98 + j*(-91) --249 + j*(-33) -9 + j*(-223) -326 + j*(-165) --135 + j*(-42) --125 + j*(-16) -15 + j*(-2) --243 + j*(-287) --33 + j*(182) --91 + j*(15) --81 + j*(-71) --194 + j*(-63) -37 + j*(-23) --138 + j*(-11) --54 + j*(100) -50 + j*(31) --43 + j*(115) --36 + j*(-128) -153 + j*(-170) -23 + j*(-226) --72 + j*(13) -130 + j*(-53) --259 + j*(93) --315 + j*(-78) --141 + j*(-96) -241 + j*(112) --54 + j*(159) -58 + j*(57) --355 + j*(63) -307 + j*(-132) -192 + j*(88) --240 + j*(15) --35 + j*(-6) -123 + j*(291) --161 + j*(158) -34 + j*(-92) -36 + j*(233) -302 + j*(-199) -71 + j*(56) --144 + j*(91) -131 + j*(276) --77 + j*(151) --110 + j*(214) -12 + j*(-490) --186 + j*(-77) -308 + j*(84) --203 + j*(3) -113 + j*(-112) --222 + j*(-176) -81 + j*(-112) -15 + j*(-14) --50 + j*(-186) -144 + j*(-47) --120 + j*(-125) -215 + j*(207) --32 + j*(-16) --383 + j*(247) --96 + j*(81) --148 + j*(-11) -48 + j*(148) -173 + j*(0) -79 + j*(390) -180 + j*(-223) -274 + j*(40) --153 + j*(47) --116 + j*(112) -121 + j*(255) -198 + j*(176) -74 + j*(134) --170 + j*(168) -91 + j*(129) -105 + j*(-324) --326 + j*(25) --109 + j*(74) -174 + j*(-59) --244 + j*(54) --314 + j*(279) --145 + j*(213) -238 + j*(103) -28 + j*(190) -46 + j*(-172) --28 + j*(-190) --122 + j*(-110) --112 + j*(-82) -298 + j*(-21) --171 + j*(83) -99 + j*(16) -143 + j*(71) --141 + j*(-247) --214 + j*(-83) --9 + j*(14) --66 + j*(-51) --175 + j*(-115) -233 + j*(-421) -117 + j*(54) -148 + j*(-204) --122 + j*(128) --4 + j*(20) --139 + j*(-47) -105 + j*(-64) -21 + j*(-56) --144 + j*(-13) --238 + j*(-225) --97 + j*(139) --83 + j*(15) -45 + j*(80) --1 + j*(173) -260 + j*(141) --125 + j*(2) -117 + j*(100) -100 + j*(-3) -255 + j*(-33) --214 + j*(-199) -243 + j*(344) -85 + j*(158) --322 + j*(-165) --214 + j*(296) --128 + j*(58) --74 + j*(-222) --25 + j*(-93) -44 + j*(5) --63 + j*(-137) --160 + j*(-328) -29 + j*(12) --78 + j*(107) -142 + j*(238) -205 + j*(-250) --207 + j*(191) -165 + j*(-142) -199 + j*(141) -28 + j*(-93) --141 + j*(175) --177 + j*(148) -274 + j*(-18) --224 + j*(-92) -17 + j*(-247) -265 + j*(-45) --121 + j*(134) --66 + j*(-78) -253 + j*(-176) --52 + j*(86) --156 + j*(13) --239 + j*(-81) -51 + j*(-115) --134 + j*(36) --83 + j*(-69) --117 + j*(78) -145 + j*(91) -288 + j*(114) -6 + j*(136) -121 + j*(240) --60 + j*(37) -197 + j*(100) --275 + j*(78) -57 + j*(321) --260 + j*(170) -91 + j*(-288) --168 + j*(-164) --171 + j*(-35) --136 + j*(344) -43 + j*(3) --206 + j*(168) --343 + j*(124) --222 + j*(-301) -98 + j*(146) --30 + j*(-252) -203 + j*(-21) --42 + j*(-90) -49 + j*(-36) --62 + j*(-53) --202 + j*(103) -2 + j*(53) -95 + j*(297) -67 + j*(-303) -183 + j*(-70) --399 + j*(74) --272 + j*(-213) --167 + j*(158) -68 + j*(-21) --180 + j*(77) -25 + j*(-18) --57 + j*(-4) -136 + j*(-37) -215 + j*(-322) -322 + j*(34) --122 + j*(-172) -185 + j*(264) --144 + j*(247) -5 + j*(-125) -36 + j*(-313) -189 + j*(5) -140 + j*(-150) -7 + j*(69) --113 + j*(11) -190 + j*(368) --284 + j*(-105) --62 + j*(5) --132 + j*(-367) --225 + j*(-90) -50 + j*(-269) -134 + j*(243) --141 + j*(-52) --226 + j*(53) -342 + j*(-53) -93 + j*(-263) --92 + j*(-141) -125 + j*(162) --123 + j*(66) -42 + j*(49) --93 + j*(-114) --92 + j*(-310) --271 + j*(-95) -114 + j*(-197) -322 + j*(158) --43 + j*(28) --215 + j*(-171) -173 + j*(204) -332 + j*(213) -94 + j*(67) -328 + j*(23) -392 + j*(-35) -155 + j*(-135) -3 + j*(315) --211 + j*(50) -226 + j*(-136) --25 + j*(-26) --126 + j*(78) --107 + j*(-45) -24 + j*(227) --100 + j*(100) -260 + j*(22) --76 + j*(390) --288 + j*(49) -66 + j*(110) --163 + j*(-91) --273 + j*(-385) -28 + j*(-218) --231 + j*(156) -47 + j*(-76) -75 + j*(-82) --43 + j*(133) -3 + j*(-226) --69 + j*(-83) -231 + j*(-101) --290 + j*(-52) -47 + j*(57) --200 + j*(89) --70 + j*(265) -55 + j*(-255) --156 + j*(127) -91 + j*(337) --3 + j*(163) --129 + j*(-339) --16 + j*(167) --245 + j*(291) --114 + j*(168) --84 + j*(-148) --7 + j*(-243) --47 + j*(-44) -166 + j*(50) -227 + j*(-92) -215 + j*(291) -149 + j*(35) --109 + j*(-145) --190 + j*(-100) --102 + j*(-8) -230 + j*(169) -16 + j*(58) -133 + j*(-169) --16 + j*(291) -267 + j*(72) -84 + j*(52) --342 + j*(73) --101 + j*(228) --16 + j*(180) --2 + j*(122) -3 + j*(-344) --93 + j*(-185) -38 + j*(92) -226 + j*(71) -390 + j*(-98) -179 + j*(-201) --180 + j*(-31) --40 + j*(-165) -109 + j*(-119) -105 + j*(-171) --322 + j*(313) --1 + j*(-18) --47 + j*(256) -282 + j*(-29) --383 + j*(-225) -284 + j*(16) -81 + j*(244) -252 + j*(279) -257 + j*(-23) --491 + j*(254) --102 + j*(175) --46 + j*(269) -102 + j*(91) -5 + j*(123) -55 + j*(69) -29 + j*(105) --197 + j*(4) --84 + j*(226) --12 + j*(95) --57 + j*(-259) -195 + j*(-243) -134 + j*(133) -25 + j*(-165) --71 + j*(-205) -91 + j*(-71) --201 + j*(18) --135 + j*(-405) -180 + j*(153) -323 + j*(276) -376 + j*(73) -221 + j*(65) --231 + j*(236) -164 + j*(156) -238 + j*(97) --18 + j*(-199) -144 + j*(-33) --231 + j*(33) --23 + j*(154) -50 + j*(24) --145 + j*(-113) -32 + j*(138) -110 + j*(-121) -168 + j*(-242) -233 + j*(20) -30 + j*(87) -115 + j*(-67) -221 + j*(-12) -23 + j*(64) -66 + j*(161) --91 + j*(-159) --98 + j*(158) --73 + j*(49) --74 + j*(-26) --209 + j*(76) -280 + j*(88) -1 + j*(-30) -474 + j*(136) --39 + j*(-202) -61 + j*(-49) --82 + j*(-31) --25 + j*(267) -110 + j*(286) --257 + j*(-42) -288 + j*(-35) -16 + j*(324) -449 + j*(-50) --169 + j*(190) -108 + j*(-13) --151 + j*(33) --21 + j*(119) -82 + j*(-81) -132 + j*(-28) --413 + j*(-19) --295 + j*(-208) -153 + j*(145) --7 + j*(194) --110 + j*(-147) --145 + j*(-126) -284 + j*(64) --81 + j*(110) -263 + j*(-72) -12 + j*(-312) --76 + j*(119) -154 + j*(52) -138 + j*(109) --98 + j*(-220) --433 + j*(-9) -267 + j*(-3) --168 + j*(203) -33 + j*(-329) -129 + j*(-35) --177 + j*(-58) --161 + j*(-55) --161 + j*(108) --168 + j*(320) --258 + j*(65) --165 + j*(30) --131 + j*(-6) --98 + j*(25) -136 + j*(410) -1 + j*(332) -6 + j*(117) --42 + j*(-151) --15 + j*(-139) -292 + j*(-97) -208 + j*(-216) -113 + j*(-93) -168 + j*(160) --261 + j*(88) -226 + j*(110) -70 + j*(-298) --221 + j*(312) -54 + j*(101) --108 + j*(166) -306 + j*(162) -75 + j*(52) --129 + j*(-223) -47 + j*(59) -235 + j*(75) --226 + j*(45) -238 + j*(91) -324 + j*(168) -132 + j*(-354) --504 + j*(151) -234 + j*(112) -236 + j*(179) --25 + j*(-47) -136 + j*(-141) -311 + j*(352) -20 + j*(-145) -61 + j*(-187) -146 + j*(-66) --111 + j*(-25) -238 + j*(-6) --248 + j*(-57) -255 + j*(169) -368 + j*(-76) -13 + j*(7) --101 + j*(33) -1 + j*(227) --243 + j*(-105) --4 + j*(59) -118 + j*(38) --23 + j*(57) -85 + j*(-116) --170 + j*(-131) --13 + j*(-11) -49 + j*(-61) --37 + j*(294) -118 + j*(308) --120 + j*(-21) --232 + j*(-107) -393 + j*(312) -25 + j*(76) -74 + j*(23) -59 + j*(-136) -306 + j*(86) --260 + j*(-314) -194 + j*(163) --199 + j*(257) --175 + j*(-257) --232 + j*(13) -240 + j*(-95) --155 + j*(-172) -361 + j*(-116) --132 + j*(-152) --110 + j*(71) --279 + j*(288) --4 + j*(-28) --12 + j*(154) -89 + j*(190) -104 + j*(42) --221 + j*(-151) --91 + j*(115) -162 + j*(-30) --471 + j*(-45) -225 + j*(-34) -161 + j*(199) -136 + j*(164) --116 + j*(87) --48 + j*(195) -74 + j*(156) --23 + j*(7) -204 + j*(166) --150 + j*(1) -19 + j*(79) -44 + j*(5) --161 + j*(76) -122 + j*(-240) -151 + j*(-18) --23 + j*(53) --227 + j*(97) --26 + j*(-221) --358 + j*(-142) -217 + j*(-240) --139 + j*(-170) -39 + j*(202) -55 + j*(-36) -122 + j*(-217) -65 + j*(242) -23 + j*(13) --46 + j*(-73) --81 + j*(-328) -131 + j*(-276) --136 + j*(186) -158 + j*(204) -100 + j*(-209) -35 + j*(43) -4 + j*(43) --263 + j*(6) --16 + j*(159) -316 + j*(139) -336 + j*(-135) --201 + j*(-235) --13 + j*(-197) -275 + j*(139) --188 + j*(13) --152 + j*(-9) --61 + j*(-177) --369 + j*(-195) -160 + j*(-98) -56 + j*(-1) --276 + j*(-13) -112 + j*(-183) --231 + j*(206) -42 + j*(-163) -76 + j*(-34) -25 + j*(-84) -62 + j*(-61) --258 + j*(-87) --145 + j*(169) --240 + j*(289) --204 + j*(-272) --191 + j*(-68) -45 + j*(91) --124 + j*(46) --261 + j*(-18) -144 + j*(340) --24 + j*(216) --7 + j*(-41) -239 + j*(52) --292 + j*(-157) -210 + j*(-414) --299 + j*(-11) -6 + j*(71) -226 + j*(-406) -27 + j*(187) --72 + j*(-43) --115 + j*(-215) -41 + j*(-39) -220 + j*(38) --158 + j*(-246) --24 + j*(-111) --69 + j*(126) -137 + j*(-32) --279 + j*(11) --98 + j*(-329) --38 + j*(68) --366 + j*(19) --94 + j*(-104) -197 + j*(-37) --93 + j*(34) --352 + j*(-19) -64 + j*(40) -165 + j*(-195) -37 + j*(42) --177 + j*(-74) --194 + j*(-129) -269 + j*(174) -55 + j*(-28) --56 + j*(-37) --309 + j*(-131) -69 + j*(-18) --173 + j*(-9) -122 + j*(-270) -64 + j*(-221) -197 + j*(66) --66 + j*(354) -1 + j*(133) --125 + j*(129) --255 + j*(-137) -180 + j*(106) --223 + j*(385) -335 + j*(42) --99 + j*(-32) -182 + j*(91) -213 + j*(29) -32 + j*(-33) --75 + j*(37) --109 + j*(-296) -134 + j*(99) --53 + j*(-76) -140 + j*(176) -248 + j*(-379) --76 + j*(-151) --132 + j*(-22) --116 + j*(110) --82 + j*(-76) --199 + j*(-174) -118 + j*(240) --144 + j*(13) --25 + j*(173) --230 + j*(-95) -125 + j*(182) --105 + j*(122) --101 + j*(195) -20 + j*(-121) -35 + j*(-342) --119 + j*(-385) --188 + j*(-165) --252 + j*(-393) --269 + j*(-127) --31 + j*(-12) -336 + j*(-78) --52 + j*(-105) --25 + j*(330) -11 + j*(149) --81 + j*(-163) --153 + j*(-223) -107 + j*(-33) --294 + j*(-106) --189 + j*(247) --218 + j*(-154) -99 + j*(-35) -127 + j*(-290) -404 + j*(-88) --135 + j*(268) -316 + j*(313) -206 + j*(161) --385 + j*(36) --17 + j*(266) -4 + j*(-23) --83 + j*(73) -0 + j*(116) -160 + j*(199) -178 + j*(-109) --69 + j*(-147) -125 + j*(59) -244 + j*(98) --146 + j*(197) -59 + j*(234) -218 + j*(386) -23 + j*(-74) -438 + j*(90) -259 + j*(55) -181 + j*(214) --38 + j*(-76) --182 + j*(55) --148 + j*(-138) --130 + j*(281) -125 + j*(-132) --90 + j*(-105) -183 + j*(255) --138 + j*(288) --165 + j*(-25) --207 + j*(427) -259 + j*(-175) -147 + j*(-359) -116 + j*(-28) --263 + j*(-146) --217 + j*(48) -9 + j*(-62) -77 + j*(-11) -61 + j*(-215) -35 + j*(66) -85 + j*(1) -6 + j*(-23) -161 + j*(37) --124 + j*(280) -111 + j*(-3) -26 + j*(233) --76 + j*(130) -15 + j*(-241) --78 + j*(-167) -44 + j*(-25) --167 + j*(205) --99 + j*(-188) --154 + j*(120) --61 + j*(11) -361 + j*(-10) -236 + j*(-204) -139 + j*(-104) --106 + j*(44) --40 + j*(99) --1 + j*(-134) --148 + j*(30) --134 + j*(54) --239 + j*(85) --275 + j*(-269) -90 + j*(-83) --225 + j*(-148) -332 + j*(-88) --47 + j*(424) --128 + j*(78) -163 + j*(69) --175 + j*(88) --146 + j*(243) -308 + j*(25) -301 + j*(26) -110 + j*(-218) --139 + j*(-78) -279 + j*(92) -161 + j*(252) --91 + j*(81) --100 + j*(11) --90 + j*(92) --98 + j*(-146) -404 + j*(216) -178 + j*(-197) --50 + j*(-149) -165 + j*(-58) -27 + j*(-303) -95 + j*(169) --108 + j*(52) -294 + j*(-26) --37 + j*(-3) --101 + j*(-292) -187 + j*(250) --71 + j*(339) -42 + j*(-67) --66 + j*(50) --37 + j*(-90) -93 + j*(56) -141 + j*(-18) -77 + j*(-32) -74 + j*(28) -248 + j*(223) -232 + j*(-345) -66 + j*(-51) -42 + j*(49) -54 + j*(113) -25 + j*(-40) --88 + j*(156) -52 + j*(-112) --214 + j*(325) -144 + j*(122) --170 + j*(147) --251 + j*(33) --195 + j*(-218) -433 + j*(224) --174 + j*(-269) --75 + j*(-378) --30 + j*(-155) -227 + j*(-212) --1 + j*(-420) --45 + j*(331) -139 + j*(-228) -114 + j*(438) -313 + j*(-54) --460 + j*(-39) -125 + j*(-170) -222 + j*(-85) --127 + j*(-302) -97 + j*(279) -114 + j*(121) --226 + j*(144) -69 + j*(10) -162 + j*(-109) -206 + j*(-395) --243 + j*(-5) --86 + j*(294) -15 + j*(68) -206 + j*(-216) --190 + j*(151) --88 + j*(-41) -44 + j*(202) --36 + j*(-110) --35 + j*(16) --29 + j*(85) -0 + j*(155) --35 + j*(-83) -221 + j*(-148) -18 + j*(-342) --83 + j*(7) --8 + j*(-144) -9 + j*(-88) --103 + j*(-317) -191 + j*(187) --337 + j*(-266) --24 + j*(8) --515 + j*(-130) --129 + j*(142) -78 + j*(138) --70 + j*(264) -117 + j*(-196) -214 + j*(263) -45 + j*(-140) -127 + j*(-354) --16 + j*(-46) --6 + j*(-17) --69 + j*(-194) -8 + j*(315) -52 + j*(119) -243 + j*(65) -19 + j*(1) --163 + j*(-174) -124 + j*(-188) --438 + j*(25) -102 + j*(-9) -88 + j*(-352) -214 + j*(-132) -150 + j*(-23) --28 + j*(58) -52 + j*(-147) --59 + j*(332) --248 + j*(88) -47 + j*(138) -210 + j*(-60) -129 + j*(-173) --54 + j*(235) --190 + j*(284) --74 + j*(142) -73 + j*(-128) --46 + j*(-215) -126 + j*(328) --136 + j*(105) --32 + j*(-168) --313 + j*(-133) -59 + j*(-33) --39 + j*(158) -93 + j*(-158) --30 + j*(-192) -119 + j*(21) --8 + j*(180) -177 + j*(-231) -211 + j*(-264) -98 + j*(146) -46 + j*(13) --170 + j*(98) -93 + j*(18) --115 + j*(-21) --86 + j*(-20) -76 + j*(325) -77 + j*(33) -199 + j*(-40) -154 + j*(-236) --14 + j*(139) -37 + j*(65) --121 + j*(36) --206 + j*(247) --18 + j*(65) -573 + j*(148) -169 + j*(-257) --64 + j*(40) -53 + j*(-59) --46 + j*(88) --197 + j*(176) -18 + j*(-134) --177 + j*(-109) --76 + j*(142) -252 + j*(-144) --2 + j*(-101) -41 + j*(-153) --109 + j*(-24) -4 + j*(141) -49 + j*(-73) --151 + j*(134) --125 + j*(151) --78 + j*(272) -49 + j*(-177) --193 + j*(-143) --164 + j*(-261) -29 + j*(-115) -195 + j*(-140) -85 + j*(13) --86 + j*(27) --77 + j*(-128) -378 + j*(114) --436 + j*(49) --55 + j*(134) --144 + j*(-27) -99 + j*(315) -92 + j*(154) -148 + j*(177) -93 + j*(83) -119 + j*(310) -190 + j*(-248) --259 + j*(-248) -218 + j*(310) -63 + j*(197) -226 + j*(81) -22 + j*(-151) -60 + j*(-168) --285 + j*(231) --40 + j*(-78) -144 + j*(-128) --20 + j*(-402) -66 + j*(-8) --71 + j*(17) -94 + j*(-111) --22 + j*(-16) -128 + j*(-156) --212 + j*(324) --320 + j*(409) --137 + j*(235) -52 + j*(-438) -205 + j*(178) -86 + j*(-149) -246 + j*(-124) -129 + j*(-48) --23 + j*(72) -54 + j*(-18) --136 + j*(225) --134 + j*(198) -255 + j*(-239) --378 + j*(-39) --23 + j*(110) -35 + j*(-124) -47 + j*(-40) -177 + j*(-16) -178 + j*(-54) --197 + j*(33) -141 + j*(-42) -134 + j*(245) -68 + j*(101) --353 + j*(-16) --375 + j*(47) -129 + j*(-129) --75 + j*(-96) -192 + j*(66) -116 + j*(41) --33 + j*(17) -103 + j*(81) --52 + j*(214) -132 + j*(59) --342 + j*(375) --308 + j*(-103) --68 + j*(140) -460 + j*(110) --18 + j*(-97) -551 + j*(-522) -243 + j*(69) -534 + j*(264) --373 + j*(-374) --543 + j*(503) -292 + j*(223) -494 + j*(-12) --96 + j*(-122) -600 + j*(-210) -378 + j*(-357) -39 + j*(477) -298 + j*(82) --46 + j*(604) --197 + j*(28) --313 + j*(460) --57 + j*(168) -368 + j*(-167) --82 + j*(-532) -12 + j*(-259) --498 + j*(-542) -567 + j*(190) -18 + j*(-402) -675 + j*(32) --188 + j*(272) -778 + j*(51) -245 + j*(479) --82 + j*(-250) -342 + j*(-177) -360 + j*(-356) -279 + j*(286) --396 + j*(-656) -154 + j*(-335) --88 + j*(-243) -327 + j*(-137) -488 + j*(274) -322 + j*(-62) --43 + j*(507) -660 + j*(265) --264 + j*(81) --158 + j*(-299) --449 + j*(-491) -557 + j*(78) --6 + j*(-75) -569 + j*(135) -478 + j*(-146) --92 + j*(-381) --289 + j*(170) -276 + j*(-35) --373 + j*(-409) --288 + j*(-107) -173 + j*(-235) -286 + j*(-235) -236 + j*(-559) -52 + j*(164) --2 + j*(-477) -169 + j*(346) --322 + j*(-5) --154 + j*(151) -250 + j*(66) --477 + j*(79) -281 + j*(-82) -214 + j*(-72) -188 + j*(394) -146 + j*(-163) --297 + j*(292) -133 + j*(-588) -648 + j*(-378) -285 + j*(453) -377 + j*(-400) -441 + j*(349) -388 + j*(-69) -396 + j*(550) --27 + j*(-142) -446 + j*(361) -255 + j*(-25) -138 + j*(-252) -443 + j*(162) -471 + j*(-293) -309 + j*(359) -187 + j*(178) -359 + j*(-255) --251 + j*(292) --246 + j*(-288) --402 + j*(427) -77 + j*(211) --254 + j*(364) -123 + j*(-347) --223 + j*(-178) --245 + j*(-308) -392 + j*(192) --302 + j*(453) --384 + j*(-284) --161 + j*(-283) -117 + j*(-281) --272 + j*(274) --211 + j*(249) --530 + j*(-353) -204 + j*(471) -23 + j*(-124) --119 + j*(-276) --35 + j*(-373) -443 + j*(-426) --23 + j*(-441) -149 + j*(-441) --160 + j*(335) -224 + j*(-366) --166 + j*(81) -30 + j*(-435) -213 + j*(-171) -337 + j*(364) --301 + j*(121) -163 + j*(358) --417 + j*(255) --170 + j*(-19) -198 + j*(-239) -418 + j*(-470) -187 + j*(225) --338 + j*(-273) --581 + j*(87) -167 + j*(-600) --685 + j*(414) -351 + j*(-370) -6 + j*(-515) --279 + j*(-240) -45 + j*(-40) --130 + j*(233) --637 + j*(-235) --187 + j*(165) --135 + j*(386) -16 + j*(355) --219 + j*(8) -469 + j*(-107) -71 + j*(108) --16 + j*(15) --14 + j*(-530) --252 + j*(68) -288 + j*(536) -288 + j*(-182) --478 + j*(-6) --134 + j*(151) --38 + j*(-388) --414 + j*(-317) -440 + j*(-426) --218 + j*(-705) --304 + j*(-85) --662 + j*(54) -273 + j*(-4) -268 + j*(211) -18 + j*(315) -141 + j*(292) -116 + j*(268) --253 + j*(146) -235 + j*(-55) --259 + j*(-178) --197 + j*(-585) --64 + j*(441) --271 + j*(-188) -358 + j*(506) -13 + j*(-94) --339 + j*(-167) -329 + j*(400) -50 + j*(-484) -91 + j*(366) --407 + j*(-144) --439 + j*(165) -170 + j*(-325) --479 + j*(355) -237 + j*(-239) -99 + j*(-355) --122 + j*(281) -515 + j*(148) --132 + j*(-269) --174 + j*(34) -11 + j*(-386) -291 + j*(-351) -243 + j*(52) --300 + j*(129) -344 + j*(-442) --232 + j*(83) --10 + j*(2) -300 + j*(733) --139 + j*(28) -83 + j*(-425) --403 + j*(-188) --344 + j*(-337) -345 + j*(144) --245 + j*(-193) --552 + j*(105) -433 + j*(-513) -426 + j*(188) -12 + j*(385) --114 + j*(-211) --261 + j*(-512) -268 + j*(139) -327 + j*(305) -309 + j*(-86) -366 + j*(407) --206 + j*(277) --81 + j*(319) --21 + j*(108) -33 + j*(-84) -234 + j*(349) --337 + j*(759) -169 + j*(324) --183 + j*(333) -1 + j*(-487) -156 + j*(-346) -240 + j*(-270) -224 + j*(-426) --71 + j*(-328) -117 + j*(-204) -79 + j*(-344) --361 + j*(113) --165 + j*(332) --582 + j*(-463) -504 + j*(204) --578 + j*(139) --26 + j*(209) --121 + j*(378) --511 + j*(55) -156 + j*(-371) -12 + j*(-390) -231 + j*(-57) -11 + j*(-35) --498 + j*(-8) --465 + j*(-315) --45 + j*(-214) -245 + j*(53) --460 + j*(-199) --151 + j*(272) --453 + j*(-342) -194 + j*(8) --68 + j*(-393) --231 + j*(168) --364 + j*(-337) --414 + j*(-211) -701 + j*(-303) --287 + j*(-534) -201 + j*(140) -177 + j*(110) --54 + j*(-180) --344 + j*(-205) -280 + j*(53) -432 + j*(-19) -376 + j*(99) -363 + j*(509) -404 + j*(-474) --279 + j*(28) --496 + j*(74) -308 + j*(-384) -680 + j*(230) -620 + j*(-209) -295 + j*(444) -194 + j*(411) --185 + j*(-2) -546 + j*(317) --5 + j*(313) --415 + j*(229) -188 + j*(429) -247 + j*(617) --12 + j*(495) -175 + j*(312) --170 + j*(-268) --74 + j*(-233) --162 + j*(-310) --210 + j*(156) -395 + j*(-435) --184 + j*(268) --24 + j*(-264) -431 + j*(-350) --389 + j*(453) --98 + j*(-118) -117 + j*(531) --165 + j*(358) -74 + j*(-362) --304 + j*(61) --199 + j*(158) -228 + j*(167) -397 + j*(170) -266 + j*(-310) -450 + j*(93) --215 + j*(-63) --231 + j*(-31) -411 + j*(-336) -443 + j*(173) -288 + j*(240) -70 + j*(208) --298 + j*(-249) -349 + j*(279) --82 + j*(-6) --282 + j*(-40) -227 + j*(-322) -93 + j*(695) --433 + j*(392) -65 + j*(-356) --249 + j*(250) -297 + j*(-205) -107 + j*(363) -95 + j*(270) -310 + j*(-12) --228 + j*(532) -111 + j*(78) -227 + j*(-24) -141 + j*(-596) --252 + j*(409) --277 + j*(-249) --53 + j*(532) --173 + j*(-244) -519 + j*(402) -18 + j*(234) --135 + j*(307) --309 + j*(95) --289 + j*(264) -289 + j*(-284) -147 + j*(-311) --377 + j*(460) --298 + j*(549) -177 + j*(332) -599 + j*(-378) -40 + j*(355) -373 + j*(121) --266 + j*(-45) --85 + j*(-47) --186 + j*(-18) --8 + j*(-195) -409 + j*(-610) -34 + j*(502) --576 + j*(78) -298 + j*(164) -409 + j*(-331) -506 + j*(-433) -460 + j*(-700) --84 + j*(269) --303 + j*(375) --5 + j*(-106) -30 + j*(85) -296 + j*(361) --179 + j*(-178) --477 + j*(-308) --141 + j*(-696) --149 + j*(398) -392 + j*(431) --300 + j*(206) --248 + j*(515) -462 + j*(217) -253 + j*(244) -164 + j*(-196) -308 + j*(-40) -28 + j*(124) --172 + j*(-233) -471 + j*(-272) -332 + j*(445) --217 + j*(200) --307 + j*(-209) -503 + j*(207) -499 + j*(378) --203 + j*(87) --273 + j*(438) -170 + j*(364) -384 + j*(-122) -291 + j*(-509) --74 + j*(422) --571 + j*(126) -76 + j*(264) --383 + j*(-128) -333 + j*(-436) --105 + j*(-313) -260 + j*(-61) -404 + j*(465) --172 + j*(363) --225 + j*(-317) -185 + j*(-140) -132 + j*(40) --199 + j*(-365) -470 + j*(-37) -89 + j*(-250) --94 + j*(256) -0 + j*(397) --326 + j*(531) --245 + j*(-2) --105 + j*(-4) -100 + j*(274) --392 + j*(-227) --274 + j*(173) --93 + j*(-418) -646 + j*(214) --568 + j*(-668) -582 + j*(16) --129 + j*(-274) -272 + j*(226) --8 + j*(-176) -351 + j*(387) -467 + j*(194) --225 + j*(166) --40 + j*(-489) -82 + j*(-408) --168 + j*(268) --28 + j*(-298) --503 + j*(-358) -94 + j*(-250) -564 + j*(41) --468 + j*(-158) -331 + j*(311) -303 + j*(-211) -185 + j*(-366) --262 + j*(171) --165 + j*(-372) --414 + j*(-305) --334 + j*(-371) --62 + j*(26) -141 + j*(208) -250 + j*(347) --256 + j*(-16) --501 + j*(552) -452 + j*(-195) --239 + j*(-151) --426 + j*(-532) -10 + j*(-282) --412 + j*(414) --482 + j*(-233) --321 + j*(256) --124 + j*(32) -409 + j*(-373) --568 + j*(-613) --311 + j*(306) --81 + j*(-678) -432 + j*(-555) --374 + j*(376) -231 + j*(-211) -404 + j*(-189) -191 + j*(403) -511 + j*(-279) --544 + j*(202) -136 + j*(-401) -363 + j*(-269) --499 + j*(-64) -385 + j*(549) -243 + j*(250) --209 + j*(393) --231 + j*(-198) -272 + j*(-286) -133 + j*(-260) --366 + j*(-317) --76 + j*(25) --270 + j*(255) --267 + j*(118) --217 + j*(-233) -313 + j*(370) -282 + j*(-179) --513 + j*(120) --118 + j*(-400) -286 + j*(-403) --231 + j*(133) --175 + j*(-118) --161 + j*(-173) --118 + j*(411) --51 + j*(-93) --542 + j*(16) -233 + j*(-422) --13 + j*(-86) -345 + j*(-467) --296 + j*(-259) --23 + j*(-313) -74 + j*(476) -182 + j*(-244) --266 + j*(-231) --251 + j*(-226) --395 + j*(-360) --156 + j*(550) -217 + j*(163) --486 + j*(433) --281 + j*(248) --65 + j*(67) -232 + j*(-296) --383 + j*(-46) -403 + j*(99) -210 + j*(-325) --217 + j*(-564) --328 + j*(169) --196 + j*(132) --624 + j*(225) --480 + j*(200) --418 + j*(307) -367 + j*(-327) --365 + j*(-371) -422 + j*(-177) -296 + j*(-316) --284 + j*(-382) -414 + j*(163) --542 + j*(-593) -332 + j*(40) --100 + j*(368) -355 + j*(-380) -542 + j*(-166) -63 + j*(267) --427 + j*(293) --83 + j*(206) --610 + j*(45) -348 + j*(-95) -469 + j*(-153) -235 + j*(-150) --285 + j*(380) --399 + j*(-140) -247 + j*(-107) --556 + j*(472) --168 + j*(-3) --204 + j*(-325) -590 + j*(303) --222 + j*(228) -200 + j*(233) -524 + j*(-117) --57 + j*(257) --405 + j*(-373) --441 + j*(-124) -16 + j*(374) -306 + j*(-499) --36 + j*(-2) --103 + j*(-356) -378 + j*(214) --361 + j*(-255) --180 + j*(328) --267 + j*(-305) -204 + j*(-63) -45 + j*(-543) --134 + j*(-142) -321 + j*(508) --412 + j*(549) --240 + j*(182) --353 + j*(177) --138 + j*(-158) -165 + j*(-395) -234 + j*(-400) --256 + j*(373) -37 + j*(-249) -69 + j*(-151) --211 + j*(-291) --209 + j*(-90) --366 + j*(-367) -555 + j*(-146) --202 + j*(-583) --280 + j*(-259) -264 + j*(-309) -595 + j*(80) --318 + j*(-107) --306 + j*(96) -128 + j*(-289) -149 + j*(65) -265 + j*(-255) --399 + j*(-277) -325 + j*(-206) --368 + j*(122) -306 + j*(-187) --261 + j*(329) --223 + j*(-4) -443 + j*(477) --476 + j*(403) -112 + j*(-310) --124 + j*(93) --25 + j*(-349) -404 + j*(-98) --134 + j*(328) --289 + j*(-192) -151 + j*(137) -431 + j*(301) --76 + j*(-70) --161 + j*(-161) --590 + j*(-261) -276 + j*(291) -232 + j*(-365) --383 + j*(-45) -409 + j*(-97) --266 + j*(366) -433 + j*(-146) --308 + j*(18) -238 + j*(80) --52 + j*(299) --250 + j*(499) --395 + j*(358) --83 + j*(-467) -173 + j*(284) -43 + j*(-25) -97 + j*(293) --46 + j*(578) -245 + j*(-372) --127 + j*(197) --59 + j*(-461) -301 + j*(358) --95 + j*(205) --132 + j*(260) --337 + j*(286) --215 + j*(-344) --224 + j*(256) -748 + j*(-341) -402 + j*(-316) -264 + j*(-693) -18 + j*(115) -127 + j*(-64) --18 + j*(-102) --95 + j*(-594) -385 + j*(72) -73 + j*(11) --237 + j*(58) --177 + j*(-98) -117 + j*(-21) --536 + j*(173) -231 + j*(89) --290 + j*(-238) -176 + j*(-135) --293 + j*(50) -112 + j*(33) -73 + j*(-214) -89 + j*(-269) -62 + j*(6) --204 + j*(9) -49 + j*(17) -21 + j*(91) --170 + j*(49) --112 + j*(-310) --247 + j*(168) --28 + j*(221) -98 + j*(-145) -234 + j*(33) --22 + j*(-23) --81 + j*(148) -69 + j*(117) --144 + j*(-127) --62 + j*(4) -76 + j*(149) -76 + j*(-45) --6 + j*(61) -75 + j*(95) --105 + j*(-210) --378 + j*(-561) --334 + j*(86) -309 + j*(-91) -309 + j*(-67) -190 + j*(-124) -91 + j*(23) -8 + j*(-58) --235 + j*(-55) -57 + j*(-322) --93 + j*(133) --189 + j*(-179) -278 + j*(-37) -177 + j*(14) --4 + j*(-166) --71 + j*(-71) -310 + j*(-178) -107 + j*(-23) -153 + j*(55) --146 + j*(350) -17 + j*(70) --94 + j*(180) --69 + j*(181) --124 + j*(-424) --75 + j*(117) --124 + j*(-28) --194 + j*(-111) -45 + j*(58) -12 + j*(-58) -197 + j*(-82) -212 + j*(32) -144 + j*(179) --9 + j*(56) --200 + j*(-328) --64 + j*(70) --48 + j*(332) --71 + j*(-75) --189 + j*(-15) -35 + j*(143) --3 + j*(148) --158 + j*(-24) --69 + j*(165) -74 + j*(73) -149 + j*(-45) --30 + j*(-211) --195 + j*(158) --147 + j*(272) -69 + j*(-50) --73 + j*(54) --309 + j*(-164) --44 + j*(-103) --401 + j*(132) --271 + j*(104) --269 + j*(-28) --303 + j*(267) --21 + j*(281) --47 + j*(34) --164 + j*(-165) --110 + j*(241) --37 + j*(62) --40 + j*(-134) -2 + j*(19) -241 + j*(-375) --301 + j*(-67) -204 + j*(-37) -303 + j*(-142) --8 + j*(184) -60 + j*(-178) --158 + j*(238) -223 + j*(-71) -63 + j*(-277) -144 + j*(-3) --375 + j*(-45) --186 + j*(6) --36 + j*(-61) -46 + j*(-59) --22 + j*(191) --127 + j*(84) --202 + j*(-13) -519 + j*(253) --378 + j*(129) -16 + j*(176) -14 + j*(66) --198 + j*(341) --16 + j*(-180) -16 + j*(54) -42 + j*(49) -116 + j*(127) -60 + j*(-39) --100 + j*(-65) -94 + j*(-66) -126 + j*(150) -396 + j*(-101) --228 + j*(-126) -188 + j*(-42) --88 + j*(-210) --1 + j*(-69) -132 + j*(85) --140 + j*(28) --165 + j*(162) --105 + j*(129) --69 + j*(-122) --130 + j*(-45) --35 + j*(-15) --217 + j*(63) -24 + j*(-269) -67 + j*(103) --230 + j*(-104) -74 + j*(-202) --48 + j*(-80) --175 + j*(-81) --118 + j*(-93) --151 + j*(-15) -300 + j*(-88) --107 + j*(-209) -113 + j*(52) -3 + j*(162) --64 + j*(-366) --180 + j*(-201) -291 + j*(65) -56 + j*(-347) --21 + j*(28) -99 + j*(154) -119 + j*(5) --18 + j*(-43) -101 + j*(-66) -279 + j*(-172) -210 + j*(-234) -119 + j*(-100) -4 + j*(-65) --221 + j*(-33) -177 + j*(33) -289 + j*(240) --134 + j*(261) --474 + j*(50) -274 + j*(-269) -79 + j*(-84) --164 + j*(63) --103 + j*(151) -25 + j*(299) -87 + j*(67) --302 + j*(93) -378 + j*(22) -230 + j*(-15) -70 + j*(-76) -74 + j*(-161) --108 + j*(46) -52 + j*(-183) --117 + j*(20) -351 + j*(-247) -169 + j*(115) -143 + j*(-125) -122 + j*(-360) -173 + j*(199) -337 + j*(-138) --255 + j*(-175) -76 + j*(108) -256 + j*(-67) -184 + j*(-215) -103 + j*(303) -244 + j*(-360) --130 + j*(-75) -98 + j*(-192) --126 + j*(244) -249 + j*(-49) -331 + j*(-116) --232 + j*(-227) -205 + j*(50) --46 + j*(156) -274 + j*(153) --392 + j*(-40) --111 + j*(-1) -45 + j*(-269) -138 + j*(22) -238 + j*(172) --24 + j*(-80) -160 + j*(-28) --56 + j*(280) --26 + j*(-56) -73 + j*(42) -360 + j*(29) -142 + j*(-410) --126 + j*(107) --134 + j*(288) -42 + j*(414) --83 + j*(-246) -170 + j*(19) -1 + j*(-26) --31 + j*(-13) -113 + j*(40) -82 + j*(145) -139 + j*(362) --89 + j*(122) --133 + j*(-552) --269 + j*(-70) --29 + j*(-21) --161 + j*(-243) --134 + j*(-10) -16 + j*(117) -13 + j*(-63) --160 + j*(252) --27 + j*(77) --252 + j*(-119) --65 + j*(167) --71 + j*(259) -62 + j*(-130) --223 + j*(117) --58 + j*(-50) -132 + j*(-72) -21 + j*(157) -56 + j*(-150) --171 + j*(-102) --42 + j*(106) --66 + j*(21) --83 + j*(119) -158 + j*(252) --252 + j*(-111) --47 + j*(92) -46 + j*(-76) --199 + j*(39) --5 + j*(-91) --65 + j*(-152) -308 + j*(-76) -36 + j*(276) --144 + j*(-122) -382 + j*(330) -212 + j*(-305) --23 + j*(-304) --19 + j*(117) -150 + j*(-267) --317 + j*(-182) --100 + j*(33) --23 + j*(92) --258 + j*(-35) -70 + j*(-20) --83 + j*(-13) -138 + j*(98) -301 + j*(-17) -448 + j*(289) -126 + j*(176) -284 + j*(12) --176 + j*(-56) -320 + j*(144) --188 + j*(-220) --7 + j*(-40) -164 + j*(-198) -23 + j*(148) -260 + j*(184) --187 + j*(-52) --47 + j*(146) --234 + j*(-148) -66 + j*(141) -243 + j*(-199) --21 + j*(-17) -178 + j*(42) -204 + j*(93) -106 + j*(135) -14 + j*(88) -135 + j*(-242) --35 + j*(-99) --186 + j*(-61) --167 + j*(-122) --21 + j*(-138) --41 + j*(-13) --83 + j*(-98) -343 + j*(-217) -180 + j*(-9) --476 + j*(-114) --110 + j*(-219) --272 + j*(211) --47 + j*(-130) --395 + j*(-134) --200 + j*(54) --107 + j*(-376) -47 + j*(298) -84 + j*(-206) --355 + j*(115) -42 + j*(147) -211 + j*(119) -18 + j*(-42) --173 + j*(77) --40 + j*(259) --168 + j*(193) --167 + j*(-274) --182 + j*(-132) -45 + j*(124) -351 + j*(-177) -170 + j*(-41) -44 + j*(90) -183 + j*(-95) --361 + j*(60) --24 + j*(-53) -122 + j*(-78) --129 + j*(-28) --160 + j*(92) -35 + j*(83) --105 + j*(41) --86 + j*(-101) --228 + j*(120) --27 + j*(-172) -36 + j*(221) -58 + j*(217) -91 + j*(-128) --58 + j*(-247) --78 + j*(270) -221 + j*(-192) -267 + j*(66) -115 + j*(48) -200 + j*(33) -155 + j*(-253) -172 + j*(93) -260 + j*(-219) -241 + j*(-64) -21 + j*(309) -37 + j*(-251) -238 + j*(-236) --4 + j*(121) -38 + j*(-204) --116 + j*(-143) -349 + j*(137) -60 + j*(23) -174 + j*(-243) -169 + j*(-221) --192 + j*(-170) -124 + j*(-182) -43 + j*(-52) -209 + j*(223) -146 + j*(172) --155 + j*(64) -28 + j*(129) --118 + j*(232) -79 + j*(-8) --294 + j*(40) --414 + j*(-79) -45 + j*(234) -50 + j*(23) --139 + j*(61) -40 + j*(41) -88 + j*(-35) -94 + j*(11) --35 + j*(-146) -54 + j*(117) --107 + j*(5) --321 + j*(-30) --190 + j*(-89) -227 + j*(90) --72 + j*(-39) --107 + j*(-324) --117 + j*(71) --33 + j*(99) --82 + j*(-171) -75 + j*(-69) -33 + j*(151) --106 + j*(-52) -35 + j*(-5) --141 + j*(441) -48 + j*(62) -5 + j*(36) -2 + j*(136) -24 + j*(303) --137 + j*(-233) --249 + j*(241) -53 + j*(-79) -92 + j*(-265) -98 + j*(210) --89 + j*(166) --18 + j*(-91) --62 + j*(-67) -74 + j*(-53) -91 + j*(-283) -330 + j*(77) --16 + j*(-185) -293 + j*(47) --54 + j*(66) -17 + j*(28) --34 + j*(49) -190 + j*(-28) --161 + j*(287) --99 + j*(187) -5 + j*(34) -21 + j*(116) --105 + j*(335) --28 + j*(-32) --74 + j*(-55) -148 + j*(69) -37 + j*(-168) --233 + j*(42) --66 + j*(-16) -115 + j*(-319) -81 + j*(-20) -120 + j*(180) -114 + j*(346) -61 + j*(-107) -143 + j*(-15) -70 + j*(-122) --119 + j*(-272) --39 + j*(129) --163 + j*(103) -76 + j*(169) --243 + j*(-21) --145 + j*(-156) --211 + j*(-214) -127 + j*(340) -79 + j*(-57) --16 + j*(-45) --24 + j*(87) -161 + j*(52) --282 + j*(212) --62 + j*(91) --44 + j*(-33) -81 + j*(151) -69 + j*(68) -237 + j*(-74) --132 + j*(260) -143 + j*(-132) --11 + j*(-6) --49 + j*(88) --28 + j*(138) --341 + j*(6) -231 + j*(35) -88 + j*(81) --4 + j*(-156) -296 + j*(79) --458 + j*(51) -35 + j*(-387) --32 + j*(-234) -88 + j*(-45) --173 + j*(-64) --33 + j*(-172) --204 + j*(-99) --202 + j*(228) -105 + j*(-313) --60 + j*(-256) --104 + j*(-276) -222 + j*(-34) --1 + j*(-357) --98 + j*(-369) --129 + j*(-107) -344 + j*(312) --262 + j*(249) -108 + j*(-228) -364 + j*(-30) --10 + j*(83) --187 + j*(23) -330 + j*(249) -57 + j*(124) -317 + j*(-185) --100 + j*(34) -225 + j*(82) --36 + j*(-7) --25 + j*(71) --90 + j*(-27) --132 + j*(155) --106 + j*(-190) --29 + j*(403) --35 + j*(209) -66 + j*(-105) -137 + j*(-29) -84 + j*(238) --1 + j*(-75) --158 + j*(-138) --120 + j*(349) --66 + j*(-279) -127 + j*(-31) --247 + j*(42) -186 + j*(-256) --69 + j*(-107) -60 + j*(280) -237 + j*(190) --161 + j*(47) --104 + j*(173) -29 + j*(11) -59 + j*(177) --43 + j*(-9) --207 + j*(248) -115 + j*(-81) --122 + j*(57) -20 + j*(-103) --25 + j*(-41) --13 + j*(66) --169 + j*(23) -16 + j*(-243) --83 + j*(-59) -121 + j*(-153) --38 + j*(-99) -269 + j*(252) -303 + j*(-616) --87 + j*(218) --23 + j*(-52) -286 + j*(147) --146 + j*(28) -185 + j*(88) -181 + j*(88) -58 + j*(300) --59 + j*(-236) --152 + j*(-32) --132 + j*(-127) --42 + j*(62) -200 + j*(-16) -178 + j*(87) --10 + j*(-289) -85 + j*(-192) -373 + j*(92) --641 + j*(26) --253 + j*(-136) --87 + j*(38) -7 + j*(-527) -79 + j*(-31) -10 + j*(76) -235 + j*(-160) -78 + j*(-93) -346 + j*(-32) -45 + j*(-271) --30 + j*(269) -180 + j*(-45) --39 + j*(125) --256 + j*(206) --24 + j*(-163) -98 + j*(317) --194 + j*(-140) --76 + j*(-12) -523 + j*(-112) -392 + j*(28) -58 + j*(-8) --118 + j*(-94) --129 + j*(17) --217 + j*(18) -200 + j*(34) --261 + j*(-148) -43 + j*(284) --160 + j*(16) -332 + j*(67) -36 + j*(-7) -324 + j*(-185) --134 + j*(-88) --43 + j*(-363) -161 + j*(-263) --59 + j*(-300) --127 + j*(164) --178 + j*(123) --146 + j*(44) --39 + j*(-35) --131 + j*(-76) --23 + j*(-384) --112 + j*(-11) -86 + j*(177) -127 + j*(107) --75 + j*(-81) -198 + j*(50) -24 + j*(-1) --17 + j*(78) --223 + j*(-136) -257 + j*(152) --81 + j*(81) --128 + j*(255) --16 + j*(201) -16 + j*(187) --143 + j*(-303) --144 + j*(-173) -95 + j*(-123) --264 + j*(177) -449 + j*(-10) -65 + j*(21) --348 + j*(129) --72 + j*(-158) --283 + j*(43) -59 + j*(-156) -113 + j*(20) --1 + j*(115) -201 + j*(25) --91 + j*(-21) -46 + j*(140) --54 + j*(-143) -71 + j*(-136) --296 + j*(-75) --202 + j*(293) --51 + j*(202) --33 + j*(88) -231 + j*(-65) -165 + j*(23) --1 + j*(165) --47 + j*(51) --4 + j*(-314) --141 + j*(-169) -53 + j*(-211) -89 + j*(204) --105 + j*(-218) -61 + j*(-53) --143 + j*(-284) --11 + j*(-369) --54 + j*(-280) -189 + j*(250) --209 + j*(-136) --65 + j*(-126) -25 + j*(168) --137 + j*(165) -41 + j*(-85) -76 + j*(231) --229 + j*(-282) -45 + j*(122) --92 + j*(66) --80 + j*(-161) -57 + j*(-59) --95 + j*(-53) --37 + j*(-35) --20 + j*(103) --124 + j*(-59) --75 + j*(21) --260 + j*(-112) -132 + j*(-57) -183 + j*(6) -243 + j*(-146) -102 + j*(384) --172 + j*(-175) -21 + j*(-363) -192 + j*(-266) -52 + j*(-297) --293 + j*(155) -58 + j*(-263) -207 + j*(14) -62 + j*(-169) --152 + j*(250) -46 + j*(-74) -95 + j*(-74) --75 + j*(147) -29 + j*(8) --140 + j*(-167) -206 + j*(-33) -249 + j*(168) -47 + j*(38) -72 + j*(-209) -52 + j*(32) -123 + j*(294) -316 + j*(-170) --91 + j*(-158) --132 + j*(-92) -124 + j*(127) -215 + j*(110) -95 + j*(141) --309 + j*(-30) -231 + j*(-153) -165 + j*(-54) -71 + j*(-115) --250 + j*(-105) --8 + j*(-131) -251 + j*(214) --199 + j*(-33) -92 + j*(-49) -86 + j*(187) --441 + j*(-16) -303 + j*(46) -163 + j*(-116) -6 + j*(45) --53 + j*(209) -97 + j*(202) -371 + j*(-264) --113 + j*(-148) --70 + j*(-216) --23 + j*(123) --88 + j*(91) --146 + j*(96) -45 + j*(-79) --67 + j*(-41) -51 + j*(-138) --203 + j*(-65) --193 + j*(214) -91 + j*(187) --246 + j*(-214) --300 + j*(153) -21 + j*(-79) --18 + j*(-130) --165 + j*(256) -88 + j*(182) --160 + j*(105) -120 + j*(-272) -440 + j*(327) -98 + j*(3) --104 + j*(107) -215 + j*(84) -398 + j*(-12) -146 + j*(32) -343 + j*(6) --522 + j*(284) -105 + j*(8) -112 + j*(41) --263 + j*(84) --36 + j*(-168) -45 + j*(90) --111 + j*(-188) -1 + j*(83) --159 + j*(40) --345 + j*(59) --17 + j*(-190) --84 + j*(134) -201 + j*(-206) -46 + j*(-110) -136 + j*(-88) -144 + j*(92) --11 + j*(-25) --102 + j*(233) --190 + j*(285) -50 + j*(123) -112 + j*(102) -72 + j*(387) -14 + j*(-137) -33 + j*(111) --60 + j*(-201) --86 + j*(118) -52 + j*(259) -52 + j*(28) -73 + j*(-199) -284 + j*(215) -296 + j*(-136) --103 + j*(146) -1 + j*(49) -120 + j*(-55) -38 + j*(187) --581 + j*(158) -163 + j*(-325) --129 + j*(-29) -257 + j*(113) -135 + j*(250) --246 + j*(-14) --285 + j*(78) --181 + j*(-91) -311 + j*(0) -75 + j*(68) -18 + j*(-100) -144 + j*(43) -324 + j*(95) --107 + j*(69) --133 + j*(-156) --203 + j*(-366) --245 + j*(-175) -72 + j*(39) --6 + j*(-11) --67 + j*(179) --26 + j*(-18) --271 + j*(375) --201 + j*(-147) --57 + j*(-52) -139 + j*(-216) --93 + j*(54) -100 + j*(373) --148 + j*(33) --171 + j*(-137) --43 + j*(98) --4 + j*(-42) --115 + j*(213) -22 + j*(-251) --165 + j*(16) --177 + j*(-170) --275 + j*(184) --153 + j*(-170) --73 + j*(-168) -11 + j*(130) -48 + j*(121) -173 + j*(125) -1 + j*(37) -66 + j*(321) -365 + j*(-200) -240 + j*(107) -231 + j*(-123) --115 + j*(41) --211 + j*(16) --192 + j*(-125) --108 + j*(50) --66 + j*(-6) --8 + j*(-118) -81 + j*(68) -372 + j*(-31) --280 + j*(66) -105 + j*(16) --97 + j*(-85) --175 + j*(-276) --52 + j*(204) --220 + j*(64) --22 + j*(-260) --138 + j*(88) --86 + j*(-236) -0 + j*(13) -40 + j*(-56) --161 + j*(-40) --106 + j*(-194) --265 + j*(-81) -86 + j*(83) --48 + j*(7) -127 + j*(-83) -218 + j*(-228) -155 + j*(88) --195 + j*(288) --69 + j*(-33) --122 + j*(36) --195 + j*(-75) --36 + j*(127) --54 + j*(119) -95 + j*(-52) -18 + j*(-72) --44 + j*(-35) -39 + j*(105) -109 + j*(-2) --190 + j*(79) -171 + j*(301) -67 + j*(-164) -93 + j*(-250) -383 + j*(30) --233 + j*(148) -64 + j*(25) --22 + j*(-25) -73 + j*(160) -457 + j*(196) --23 + j*(6) -154 + j*(35) --78 + j*(-95) -18 + j*(-118) --17 + j*(100) -125 + j*(-159) --107 + j*(47) -18 + j*(342) --83 + j*(-453) -411 + j*(157) -83 + j*(-192) -143 + j*(-182) --266 + j*(-77) -124 + j*(-392) -94 + j*(-190) --200 + j*(261) --146 + j*(-107) -80 + j*(-24) --113 + j*(57) --4 + j*(87) -78 + j*(32) --257 + j*(-225) -252 + j*(98) -121 + j*(222) -20 + j*(15) --233 + j*(-42) --76 + j*(-408) --141 + j*(40) -146 + j*(-282) -52 + j*(-11) -88 + j*(-210) -93 + j*(157) -112 + j*(270) -45 + j*(34) -3 + j*(-139) -20 + j*(197) -86 + j*(-23) --154 + j*(-133) -98 + j*(-40) --356 + j*(-88) --159 + j*(-144) -235 + j*(289) -7 + j*(-182) --52 + j*(-290) -589 + j*(-199) --26 + j*(-64) -14 + j*(-146) --436 + j*(45) --8 + j*(339) --64 + j*(-50) --325 + j*(53) -83 + j*(223) --16 + j*(-254) -192 + j*(-69) -251 + j*(-84) -228 + j*(8) -114 + j*(163) --55 + j*(84) -10 + j*(-61) -193 + j*(84) --214 + j*(-66) --49 + j*(69) --231 + j*(-11) --22 + j*(-81) --199 + j*(90) -264 + j*(138) --331 + j*(71) -132 + j*(122) -147 + j*(7) --77 + j*(-69) -86 + j*(-34) --98 + j*(143) --408 + j*(153) -243 + j*(32) --192 + j*(45) -210 + j*(-25) -2 + j*(16) --516 + j*(-149) -80 + j*(-56) --145 + j*(54) -108 + j*(8) --151 + j*(59) --255 + j*(200) -28 + j*(30) --170 + j*(-214) --14 + j*(14) -221 + j*(3) --190 + j*(-98) --173 + j*(-229) --131 + j*(-164) -313 + j*(-194) -97 + j*(112) -222 + j*(-268) -13 + j*(-59) -117 + j*(-142) -172 + j*(-177) -67 + j*(221) --87 + j*(-32) --144 + j*(93) --135 + j*(-286) -385 + j*(-101) --86 + j*(202) --149 + j*(127) --56 + j*(195) --2 + j*(-35) --5 + j*(-182) -195 + j*(170) -202 + j*(-215) --213 + j*(-109) -101 + j*(-176) -255 + j*(-240) --86 + j*(214) --165 + j*(-35) -242 + j*(-112) --18 + j*(-156) -81 + j*(-96) --4 + j*(120) --97 + j*(8) -217 + j*(195) -256 + j*(-281) -71 + j*(-104) --125 + j*(153) --89 + j*(86) --69 + j*(210) --45 + j*(4) -445 + j*(-89) --50 + j*(-165) --212 + j*(58) -405 + j*(202) -153 + j*(383) --74 + j*(199) -317 + j*(-228) --6 + j*(-18) -24 + j*(-126) -234 + j*(141) --113 + j*(-23) -128 + j*(80) -202 + j*(194) -52 + j*(110) --8 + j*(-151) --58 + j*(132) --171 + j*(115) -54 + j*(49) --151 + j*(-103) -132 + j*(-243) -276 + j*(-27) --361 + j*(-115) --150 + j*(84) --148 + j*(-176) --145 + j*(82) -219 + j*(-160) -184 + j*(-7) -33 + j*(-124) --95 + j*(114) -190 + j*(-218) -141 + j*(-73) --187 + j*(190) --1 + j*(9) -149 + j*(6) -254 + j*(-40) --35 + j*(-286) -151 + j*(303) --139 + j*(-175) --104 + j*(49) --400 + j*(-63) -92 + j*(-197) --318 + j*(10) -25 + j*(-160) --183 + j*(-194) -74 + j*(45) -33 + j*(-66) -124 + j*(-181) --93 + j*(74) -206 + j*(-126) -257 + j*(-97) -18 + j*(9) --128 + j*(64) -119 + j*(125) --140 + j*(11) --257 + j*(7) --356 + j*(-113) --295 + j*(287) --144 + j*(104) -174 + j*(59) --13 + j*(-155) --43 + j*(92) --238 + j*(-49) --195 + j*(238) -112 + j*(-262) --103 + j*(37) -45 + j*(-238) --217 + j*(-295) --153 + j*(156) -281 + j*(88) --107 + j*(-43) -293 + j*(47) --215 + j*(80) --48 + j*(-238) --395 + j*(122) --348 + j*(-60) -11 + j*(40) -216 + j*(56) --78 + j*(163) -8 + j*(-216) -105 + j*(91) -106 + j*(261) --95 + j*(-192) -112 + j*(67) -312 + j*(-171) -168 + j*(-223) --7 + j*(171) --27 + j*(-176) -166 + j*(206) -40 + j*(89) --80 + j*(-222) --120 + j*(-236) --173 + j*(-10) --48 + j*(-100) --228 + j*(-205) -303 + j*(134) -222 + j*(18) --118 + j*(203) --35 + j*(40) -29 + j*(-70) -226 + j*(-18) -164 + j*(59) -173 + j*(-224) -45 + j*(-255) -149 + j*(-78) --10 + j*(-176) --168 + j*(216) -60 + j*(46) -45 + j*(-16) --254 + j*(-35) -116 + j*(28) -87 + j*(170) -91 + j*(-139) -204 + j*(-61) --131 + j*(-184) -158 + j*(184) --118 + j*(-86) -475 + j*(158) -255 + j*(-69) -54 + j*(-293) --11 + j*(91) --74 + j*(-40) --122 + j*(245) --371 + j*(-127) --13 + j*(-100) --156 + j*(1) -71 + j*(-356) --117 + j*(1) --56 + j*(319) --126 + j*(-319) --159 + j*(-66) --115 + j*(188) --153 + j*(257) -187 + j*(-379) -64 + j*(-60) --56 + j*(6) --279 + j*(-78) -437 + j*(-305) -164 + j*(161) -371 + j*(-175) -76 + j*(143) -240 + j*(-185) -14 + j*(187) -381 + j*(134) -65 + j*(-382) -274 + j*(-39) -91 + j*(78) --284 + j*(24) -115 + j*(82) --64 + j*(194) -33 + j*(182) --130 + j*(-107) --77 + j*(-45) --229 + j*(-103) -199 + j*(594) -117 + j*(59) -143 + j*(-350) -123 + j*(31) --86 + j*(-33) --301 + j*(258) -18 + j*(322) -166 + j*(-163) -157 + j*(-4) -201 + j*(228) --115 + j*(-309) --33 + j*(-49) --257 + j*(1) -75 + j*(-115) -45 + j*(367) --37 + j*(-36) --77 + j*(-276) -163 + j*(138) --42 + j*(103) -13 + j*(-232) -56 + j*(110) --30 + j*(-88) --47 + j*(-7) -42 + j*(235) -151 + j*(-332) -257 + j*(-101) -152 + j*(216) --316 + j*(212) --92 + j*(115) -127 + j*(-179) --67 + j*(47) --197 + j*(26) -441 + j*(-165) --227 + j*(124) -49 + j*(45) --81 + j*(368) --62 + j*(-108) -251 + j*(-332) --36 + j*(-64) -147 + j*(-291) --129 + j*(-181) -226 + j*(-194) --74 + j*(-160) --250 + j*(-107) --322 + j*(72) --95 + j*(15) --130 + j*(14) --42 + j*(-41) -23 + j*(-275) --61 + j*(-23) --400 + j*(257) -73 + j*(-130) --119 + j*(-42) --28 + j*(-104) -27 + j*(-366) --64 + j*(209) -84 + j*(206) --176 + j*(-442) -103 + j*(-235) --76 + j*(-279) -99 + j*(52) --264 + j*(-8) --288 + j*(71) -14 + j*(24) --402 + j*(25) --299 + j*(156) --146 + j*(135) --21 + j*(187) --255 + j*(-52) --214 + j*(239) -106 + j*(-19) -63 + j*(-71) -25 + j*(-88) -220 + j*(426) --358 + j*(91) --252 + j*(-223) --54 + j*(-177) -122 + j*(-41) -105 + j*(-161) --65 + j*(84) -252 + j*(10) --168 + j*(-198) -183 + j*(-35) -11 + j*(172) --226 + j*(-230) --184 + j*(-214) --151 + j*(-233) --92 + j*(-59) -31 + j*(100) -16 + j*(331) -125 + j*(81) --301 + j*(-35) -69 + j*(-139) --60 + j*(107) --64 + j*(-63) --43 + j*(-99) --130 + j*(-54) -134 + j*(381) --155 + j*(17) --499 + j*(223) --148 + j*(-124) --95 + j*(226) -247 + j*(-55) --181 + j*(-183) --94 + j*(-284) --287 + j*(-103) --136 + j*(59) -59 + j*(67) -259 + j*(-352) --150 + j*(-10) --43 + j*(119) -69 + j*(30) --106 + j*(351) --38 + j*(-85) -366 + j*(249) -71 + j*(197) -215 + j*(-37) --136 + j*(196) --231 + j*(75) -97 + j*(-383) -103 + j*(95) -99 + j*(-164) -172 + j*(-106) -93 + j*(177) -42 + j*(-337) --23 + j*(-7) -199 + j*(262) --141 + j*(70) -60 + j*(-132) --5 + j*(-18) --40 + j*(117) --18 + j*(127) --224 + j*(245) --200 + j*(-121) --22 + j*(74) --23 + j*(-212) -129 + j*(119) -42 + j*(286) -18 + j*(261) --17 + j*(-211) --72 + j*(84) -327 + j*(-28) -2 + j*(-11) -100 + j*(-301) --37 + j*(9) --66 + j*(-165) -16 + j*(-57) --59 + j*(-22) -49 + j*(158) -338 + j*(144) -11 + j*(87) --276 + j*(-42) --20 + j*(226) --117 + j*(0) --199 + j*(-294) --274 + j*(18) --21 + j*(-148) --173 + j*(216) -103 + j*(101) -162 + j*(18) -301 + j*(157) --43 + j*(486) -174 + j*(-354) --61 + j*(-138) --62 + j*(-337) -24 + j*(161) -106 + j*(-105) -69 + j*(-204) -247 + j*(166) --199 + j*(235) -11 + j*(107) -273 + j*(180) -157 + j*(-83) -174 + j*(21) --88 + j*(192) --171 + j*(-54) -393 + j*(294) --23 + j*(-21) --6 + j*(4) --73 + j*(-25) --319 + j*(-282) --407 + j*(-130) -86 + j*(76) -293 + j*(52) -392 + j*(-10) --297 + j*(-74) -89 + j*(-230) --149 + j*(286) --185 + j*(43) --91 + j*(-103) --277 + j*(-305) --189 + j*(-58) --190 + j*(-8) --54 + j*(-74) -99 + j*(26) --83 + j*(-206) -223 + j*(82) --60 + j*(-88) -342 + j*(-260) --350 + j*(-141) -154 + j*(-4) -48 + j*(-197) -153 + j*(211) -223 + j*(118) -52 + j*(-206) -158 + j*(-131) --368 + j*(49) --180 + j*(-28) -19 + j*(-435) -112 + j*(83) --167 + j*(-94) -161 + j*(284) -317 + j*(196) --108 + j*(-390) --236 + j*(105) --287 + j*(-153) --87 + j*(-1) --42 + j*(-37) --77 + j*(-438) --9 + j*(59) -48 + j*(-317) -395 + j*(133) --83 + j*(86) --60 + j*(16) --31 + j*(-90) -144 + j*(-65) --80 + j*(-160) -42 + j*(-12) --260 + j*(247) --56 + j*(185) -16 + j*(70) --87 + j*(-107) -74 + j*(187) --37 + j*(210) -303 + j*(52) --42 + j*(323) --40 + j*(-14) -54 + j*(119) --30 + j*(100) --129 + j*(-9) -223 + j*(11) --103 + j*(34) -225 + j*(316) --11 + j*(-108) --141 + j*(204) -86 + j*(-39) -50 + j*(361) --120 + j*(-119) -233 + j*(-174) --277 + j*(-74) --126 + j*(169) -58 + j*(-33) --177 + j*(-51) --153 + j*(-271) -151 + j*(119) -215 + j*(18) --69 + j*(-188) -305 + j*(130) --144 + j*(7) --210 + j*(50) -190 + j*(148) -78 + j*(-69) -37 + j*(96) -42 + j*(209) -243 + j*(57) -103 + j*(-252) --69 + j*(101) --43 + j*(-157) --168 + j*(-206) -27 + j*(-35) -100 + j*(-18) -6 + j*(33) --52 + j*(5) -13 + j*(-250) -17 + j*(268) -204 + j*(-153) -210 + j*(-54) --117 + j*(85) --30 + j*(22) --255 + j*(19) --3 + j*(-106) --87 + j*(-130) -50 + j*(-207) -340 + j*(143) --350 + j*(-105) -190 + j*(62) -32 + j*(-141) -21 + j*(289) --322 + j*(394) -29 + j*(-30) -132 + j*(-94) -114 + j*(-328) --195 + j*(372) --228 + j*(-20) -54 + j*(66) --39 + j*(-59) -186 + j*(10) -153 + j*(258) -12 + j*(45) -4 + j*(-96) --33 + j*(54) --210 + j*(116) --369 + j*(72) -28 + j*(180) -93 + j*(114) --98 + j*(208) -211 + j*(119) --148 + j*(-176) --391 + j*(-227) --63 + j*(122) -59 + j*(30) -41 + j*(269) --97 + j*(200) --49 + j*(-78) --208 + j*(261) -25 + j*(-16) --253 + j*(8) -146 + j*(68) -71 + j*(28) -221 + j*(-176) --281 + j*(-49) -278 + j*(134) -83 + j*(168) --66 + j*(543) -260 + j*(-264) --245 + j*(-107) --205 + j*(669) --275 + j*(207) --265 + j*(294) -88 + j*(137) --162 + j*(-23) --410 + j*(-24) --228 + j*(-286) -486 + j*(-153) --10 + j*(112) -113 + j*(-173) -317 + j*(-373) --211 + j*(-313) --163 + j*(-56) -362 + j*(-64) -83 + j*(397) --247 + j*(312) -385 + j*(-145) --151 + j*(74) -361 + j*(161) --247 + j*(451) --320 + j*(-274) -314 + j*(337) -155 + j*(233) -114 + j*(-267) -115 + j*(201) -377 + j*(-134) -194 + j*(218) -36 + j*(202) --598 + j*(232) -122 + j*(-301) -411 + j*(256) -260 + j*(-323) -12 + j*(466) --78 + j*(-218) -267 + j*(-318) --243 + j*(-390) -573 + j*(441) --57 + j*(-368) --492 + j*(141) --271 + j*(-62) -310 + j*(246) -226 + j*(-334) --395 + j*(-523) --323 + j*(166) --339 + j*(-184) -283 + j*(90) --737 + j*(-246) -196 + j*(335) -354 + j*(-433) --33 + j*(13) --402 + j*(-357) -322 + j*(209) -69 + j*(109) -453 + j*(-119) -245 + j*(34) -296 + j*(-48) -283 + j*(-426) -228 + j*(-288) -86 + j*(185) -453 + j*(-25) --137 + j*(255) -77 + j*(-154) --166 + j*(-66) --342 + j*(179) --454 + j*(-412) -387 + j*(-252) -292 + j*(122) -334 + j*(0) --254 + j*(129) --116 + j*(-10) --292 + j*(-6) -268 + j*(-445) --209 + j*(-537) -424 + j*(-64) -279 + j*(-367) --361 + j*(-91) --243 + j*(-316) -250 + j*(-355) -238 + j*(-216) --464 + j*(386) --296 + j*(150) --192 + j*(-322) -151 + j*(-255) -341 + j*(361) --467 + j*(269) --282 + j*(-421) -180 + j*(-375) --428 + j*(-371) -211 + j*(272) -65 + j*(-426) --378 + j*(-335) -158 + j*(-18) --214 + j*(195) --12 + j*(-337) --115 + j*(116) -433 + j*(-126) -228 + j*(-88) --329 + j*(54) -425 + j*(-19) --443 + j*(496) -358 + j*(-255) --401 + j*(272) -285 + j*(172) --81 + j*(405) -10 + j*(-358) --370 + j*(102) --477 + j*(30) -8 + j*(519) --323 + j*(447) --527 + j*(-167) --218 + j*(36) --116 + j*(-40) -501 + j*(-393) -180 + j*(-192) --93 + j*(-530) --57 + j*(-521) -21 + j*(-306) -252 + j*(228) --330 + j*(-42) -35 + j*(-476) --482 + j*(-399) -221 + j*(348) --257 + j*(-202) --110 + j*(-249) -313 + j*(-1) --303 + j*(51) --374 + j*(683) -339 + j*(279) -428 + j*(363) -18 + j*(-341) -355 + j*(508) --128 + j*(265) --309 + j*(-98) --28 + j*(-35) --439 + j*(231) -499 + j*(458) --546 + j*(-80) --31 + j*(395) --47 + j*(-1) -135 + j*(-437) -299 + j*(126) -161 + j*(424) -275 + j*(-41) --172 + j*(77) --433 + j*(57) -477 + j*(-182) -334 + j*(349) -233 + j*(-412) -414 + j*(93) -93 + j*(103) --146 + j*(-267) --232 + j*(-346) -324 + j*(204) --500 + j*(-10) -276 + j*(-453) -23 + j*(-245) -343 + j*(-359) -419 + j*(-468) -517 + j*(83) -332 + j*(583) -355 + j*(-421) --238 + j*(-115) -729 + j*(-23) -218 + j*(148) -305 + j*(-159) --265 + j*(102) --346 + j*(109) -343 + j*(140) -504 + j*(-364) --424 + j*(-228) --202 + j*(64) --35 + j*(265) --456 + j*(599) --388 + j*(-223) -83 + j*(-33) -375 + j*(-334) --115 + j*(53) -383 + j*(387) -110 + j*(-587) -518 + j*(49) -318 + j*(418) --219 + j*(-455) --37 + j*(-326) --233 + j*(182) --334 + j*(406) -559 + j*(327) --398 + j*(265) --517 + j*(-204) -436 + j*(204) -260 + j*(644) -407 + j*(-289) -355 + j*(-119) -377 + j*(-563) -171 + j*(-69) -313 + j*(-574) -228 + j*(-445) --118 + j*(-154) --161 + j*(424) -124 + j*(-366) -335 + j*(-135) --99 + j*(-424) -437 + j*(506) -490 + j*(747) -272 + j*(79) --28 + j*(-279) -214 + j*(333) --190 + j*(251) -220 + j*(-320) -18 + j*(298) -292 + j*(136) --164 + j*(-386) --437 + j*(373) --122 + j*(-311) -59 + j*(-512) -115 + j*(-47) -371 + j*(105) -432 + j*(-331) --418 + j*(247) --438 + j*(356) -231 + j*(-129) --334 + j*(178) --309 + j*(-184) -269 + j*(460) --460 + j*(118) -537 + j*(36) -550 + j*(224) -275 + j*(-334) --344 + j*(245) --120 + j*(-237) -122 + j*(-154) -68 + j*(-146) -68 + j*(-363) --211 + j*(-162) --258 + j*(-269) -560 + j*(-274) -145 + j*(-81) -562 + j*(231) --363 + j*(-486) -429 + j*(-189) -317 + j*(286) -298 + j*(-331) -110 + j*(-121) -4 + j*(-651) -4 + j*(648) -318 + j*(506) -478 + j*(79) -103 + j*(40) --136 + j*(-419) -412 + j*(-26) --493 + j*(290) --364 + j*(513) -158 + j*(35) --472 + j*(-109) --293 + j*(-365) -372 + j*(437) --171 + j*(-282) --439 + j*(202) --136 + j*(202) --196 + j*(427) --387 + j*(283) --329 + j*(118) --320 + j*(-251) --141 + j*(382) -290 + j*(-96) -262 + j*(-165) --173 + j*(-39) -126 + j*(-477) --247 + j*(299) --247 + j*(382) --315 + j*(356) -141 + j*(-220) -291 + j*(-223) -281 + j*(448) -287 + j*(90) -457 + j*(-190) --184 + j*(438) -302 + j*(-472) --176 + j*(286) --207 + j*(-400) -439 + j*(-117) -74 + j*(125) -292 + j*(-349) -299 + j*(-208) --30 + j*(-268) --59 + j*(-288) --226 + j*(-315) --499 + j*(-209) --340 + j*(423) --389 + j*(-105) --170 + j*(-335) --76 + j*(225) --312 + j*(88) -379 + j*(303) -284 + j*(-255) --291 + j*(296) -601 + j*(220) -207 + j*(105) -148 + j*(313) -281 + j*(420) --402 + j*(382) --141 + j*(148) --74 + j*(318) --618 + j*(-348) --385 + j*(-310) -448 + j*(233) -471 + j*(-279) -9 + j*(125) --191 + j*(-74) -559 + j*(529) --421 + j*(-25) -615 + j*(-308) --161 + j*(370) -493 + j*(-135) --39 + j*(-309) --270 + j*(-256) -527 + j*(8) --204 + j*(474) -88 + j*(514) --276 + j*(-429) -238 + j*(277) --216 + j*(165) --202 + j*(-349) --73 + j*(-279) -267 + j*(279) --186 + j*(-200) --404 + j*(639) -233 + j*(-351) -304 + j*(-202) --91 + j*(-161) -383 + j*(-247) --437 + j*(-287) --275 + j*(-8) -453 + j*(-290) -305 + j*(-100) -323 + j*(-377) -22 + j*(112) --371 + j*(-85) --23 + j*(-8) -276 + j*(173) -226 + j*(120) --491 + j*(337) --245 + j*(497) -368 + j*(-130) -77 + j*(190) -378 + j*(34) --298 + j*(187) -146 + j*(322) --494 + j*(-216) --312 + j*(80) -361 + j*(195) -213 + j*(-537) --49 + j*(-452) --282 + j*(-228) --171 + j*(382) -74 + j*(-387) --382 + j*(378) -513 + j*(-339) -67 + j*(-65) -301 + j*(-3) -438 + j*(-215) --516 + j*(100) -55 + j*(-149) --47 + j*(-359) -92 + j*(-285) --182 + j*(193) -152 + j*(-314) --270 + j*(255) --334 + j*(-128) -299 + j*(-450) --197 + j*(311) --231 + j*(-173) -458 + j*(-262) --206 + j*(477) --338 + j*(202) --37 + j*(454) --477 + j*(-1) --157 + j*(-477) --339 + j*(-322) --278 + j*(607) -257 + j*(-292) --199 + j*(77) -132 + j*(182) --314 + j*(-312) --439 + j*(366) --319 + j*(-279) -358 + j*(74) --198 + j*(-170) -557 + j*(-256) --207 + j*(-424) --472 + j*(-307) -158 + j*(228) --80 + j*(-64) -395 + j*(383) --168 + j*(-6) --40 + j*(-215) -78 + j*(-342) --28 + j*(97) -357 + j*(73) --584 + j*(-170) --510 + j*(296) --155 + j*(42) -187 + j*(13) -510 + j*(334) -113 + j*(-436) --448 + j*(265) --327 + j*(184) -128 + j*(141) -211 + j*(-30) -139 + j*(197) --36 + j*(65) -546 + j*(220) -473 + j*(-143) --139 + j*(175) --473 + j*(243) -247 + j*(-214) -18 + j*(262) -28 + j*(-354) -140 + j*(-25) --325 + j*(-457) --284 + j*(-313) -229 + j*(-353) --337 + j*(-385) -448 + j*(501) --292 + j*(-126) -484 + j*(-617) --291 + j*(-453) --297 + j*(-247) -347 + j*(-323) -204 + j*(-272) --252 + j*(-155) --148 + j*(-477) -166 + j*(378) -142 + j*(0) -174 + j*(438) -653 + j*(-51) -259 + j*(458) --282 + j*(237) -13 + j*(350) --537 + j*(365) -215 + j*(315) -467 + j*(129) -244 + j*(-213) -285 + j*(1) -182 + j*(-56) -135 + j*(-305) -208 + j*(-312) -612 + j*(-123) -303 + j*(473) -102 + j*(-471) --190 + j*(-270) -3 + j*(-470) -192 + j*(483) -94 + j*(-435) --69 + j*(333) -527 + j*(9) --203 + j*(201) -159 + j*(1) --428 + j*(333) -54 + j*(-194) -391 + j*(303) --171 + j*(-295) -315 + j*(-127) -260 + j*(197) --146 + j*(-67) -297 + j*(446) --474 + j*(285) --95 + j*(165) -286 + j*(-295) --482 + j*(-386) -37 + j*(-359) --295 + j*(-119) -187 + j*(-374) -359 + j*(-55) --294 + j*(-349) -301 + j*(301) -148 + j*(-211) --259 + j*(-183) --325 + j*(28) --144 + j*(39) --403 + j*(-242) --465 + j*(49) -176 + j*(-325) -262 + j*(-41) -547 + j*(260) --316 + j*(65) -425 + j*(-1) -310 + j*(-226) --163 + j*(-569) --361 + j*(268) -385 + j*(-217) --474 + j*(-19) --143 + j*(238) --280 + j*(-138) -170 + j*(233) -124 + j*(-78) -593 + j*(348) --291 + j*(-136) -98 + j*(542) --211 + j*(-704) -431 + j*(-303) -79 + j*(-228) -134 + j*(-62) --247 + j*(-397) -567 + j*(52) -521 + j*(-226) -368 + j*(-127) --654 + j*(28) --457 + j*(595) --162 + j*(-465) --161 + j*(-552) -202 + j*(-199) --409 + j*(-440) -623 + j*(137) -305 + j*(6) --115 + j*(-160) -206 + j*(-120) -182 + j*(285) --478 + j*(-85) --197 + j*(-403) -119 + j*(-354) --308 + j*(349) -482 + j*(-368) --296 + j*(96) --27 + j*(141) -665 + j*(389) -458 + j*(179) --8 + j*(-435) --648 + j*(-80) --403 + j*(192) --212 + j*(161) -319 + j*(-486) -222 + j*(-178) -308 + j*(338) --88 + j*(-101) -406 + j*(-424) --95 + j*(-590) --412 + j*(-542) --64 + j*(-274) --245 + j*(320) -144 + j*(192) -144 + j*(300) -225 + j*(-187) --200 + j*(352) --576 + j*(-369) -86 + j*(-57) -243 + j*(-177) --106 + j*(-433) -275 + j*(361) -85 + j*(164) --300 + j*(338) --659 + j*(-456) --293 + j*(-298) --453 + j*(209) --493 + j*(165) --635 + j*(-501) --353 + j*(357) --294 + j*(184) -47 + j*(-356) -251 + j*(37) -490 + j*(250) --204 + j*(-330) -344 + j*(291) -110 + j*(165) -97 + j*(18) -540 + j*(-192) --569 + j*(-88) --135 + j*(95) --326 + j*(-617) -115 + j*(-14) -263 + j*(-353) -436 + j*(-301) -83 + j*(265) --94 + j*(269) --194 + j*(-245) --6 + j*(-158) --156 + j*(-540) -476 + j*(313) -308 + j*(-288) --74 + j*(-361) --286 + j*(-144) -332 + j*(-60) -327 + j*(147) --452 + j*(477) -95 + j*(116) -477 + j*(413) -343 + j*(427) -548 + j*(351) --358 + j*(108) --147 + j*(-146) --383 + j*(-209) --431 + j*(-528) -555 + j*(473) -233 + j*(-53) --44 + j*(-122) -339 + j*(626) --10 + j*(-454) --10 + j*(484) --222 + j*(225) --47 + j*(90) -170 + j*(162) -61 + j*(-95) -25 + j*(-11) -74 + j*(269) --2 + j*(243) -3 + j*(30) --267 + j*(-80) -59 + j*(374) --35 + j*(-372) -165 + j*(221) --102 + j*(-175) --34 + j*(-115) --75 + j*(-95) -126 + j*(88) --245 + j*(194) --351 + j*(72) -33 + j*(47) --87 + j*(-266) --95 + j*(165) --56 + j*(42) -179 + j*(123) --30 + j*(170) -5 + j*(-428) -279 + j*(346) --349 + j*(-42) --9 + j*(-86) --62 + j*(293) -344 + j*(-372) -148 + j*(-54) --160 + j*(-57) --57 + j*(109) --88 + j*(128) --73 + j*(156) --130 + j*(60) --206 + j*(472) --129 + j*(4) -231 + j*(-168) --84 + j*(-132) --189 + j*(310) --64 + j*(-107) -274 + j*(-236) --53 + j*(-1) -8 + j*(-197) -327 + j*(-13) -85 + j*(321) -41 + j*(158) -134 + j*(267) -53 + j*(129) -42 + j*(-11) -144 + j*(-164) -216 + j*(29) --70 + j*(-49) --153 + j*(-78) -303 + j*(91) -248 + j*(-240) -60 + j*(191) -51 + j*(51) -38 + j*(30) --110 + j*(72) -395 + j*(-380) --98 + j*(-201) --21 + j*(-40) -26 + j*(122) -6 + j*(268) --85 + j*(78) -105 + j*(49) -152 + j*(-69) -277 + j*(134) -59 + j*(-185) --112 + j*(-143) --12 + j*(275) --103 + j*(-44) --190 + j*(-227) --245 + j*(105) --21 + j*(-148) --67 + j*(45) -154 + j*(128) --110 + j*(-153) --33 + j*(-143) --88 + j*(-81) -163 + j*(-1) -42 + j*(-227) -93 + j*(1) -202 + j*(-52) -305 + j*(58) --170 + j*(-458) --181 + j*(418) -291 + j*(402) --198 + j*(166) -196 + j*(-259) --263 + j*(186) -77 + j*(137) -59 + j*(-204) -379 + j*(-7) --19 + j*(64) -235 + j*(35) -81 + j*(-90) -24 + j*(79) -54 + j*(-92) --119 + j*(-243) -99 + j*(187) --18 + j*(109) -139 + j*(-76) --267 + j*(-52) --111 + j*(92) -6 + j*(-2) -57 + j*(158) -158 + j*(-405) --224 + j*(242) -271 + j*(-42) -131 + j*(-201) -151 + j*(192) --50 + j*(42) -333 + j*(-21) --34 + j*(-134) --121 + j*(110) --480 + j*(-63) -40 + j*(-447) --150 + j*(147) -90 + j*(-212) --186 + j*(-5) -174 + j*(-49) --319 + j*(91) -145 + j*(-51) --251 + j*(-44) -57 + j*(13) --9 + j*(-190) --72 + j*(107) -54 + j*(114) -156 + j*(20) --134 + j*(98) --89 + j*(-16) --120 + j*(-82) --135 + j*(-173) -307 + j*(-235) --24 + j*(-242) -132 + j*(-212) --139 + j*(-104) -349 + j*(-211) -23 + j*(146) -65 + j*(25) --104 + j*(140) --110 + j*(115) --97 + j*(-174) -162 + j*(35) -86 + j*(-174) -222 + j*(48) -136 + j*(279) --100 + j*(-28) --5 + j*(-159) -49 + j*(-167) --3 + j*(230) --57 + j*(12) -136 + j*(-295) -62 + j*(-274) --178 + j*(-213) --34 + j*(284) -102 + j*(174) --112 + j*(83) -99 + j*(161) --141 + j*(-249) -16 + j*(21) -135 + j*(-135) -62 + j*(162) -23 + j*(-67) --128 + j*(-1) --24 + j*(-153) -8 + j*(128) -134 + j*(-47) --240 + j*(185) -18 + j*(310) --136 + j*(108) --266 + j*(-65) -174 + j*(33) --188 + j*(18) --146 + j*(180) -128 + j*(-28) -339 + j*(157) --163 + j*(215) -148 + j*(26) --57 + j*(-83) --116 + j*(82) --91 + j*(110) --258 + j*(1) --128 + j*(-60) -26 + j*(-158) --87 + j*(-183) -1 + j*(12) --73 + j*(313) -265 + j*(-34) --39 + j*(-241) --30 + j*(66) -81 + j*(-78) -97 + j*(-133) --57 + j*(-127) -94 + j*(-61) -228 + j*(-84) --77 + j*(276) -76 + j*(86) --38 + j*(-375) --130 + j*(136) --11 + j*(-57) --182 + j*(25) -40 + j*(-249) --206 + j*(100) -0 + j*(119) --240 + j*(-139) --165 + j*(55) -170 + j*(-28) -361 + j*(-87) -91 + j*(132) -10 + j*(139) --154 + j*(-103) -37 + j*(39) --142 + j*(-283) -181 + j*(207) --1 + j*(-238) --273 + j*(93) -27 + j*(-272) --78 + j*(-228) -322 + j*(-95) --100 + j*(-489) --257 + j*(-308) --112 + j*(302) -145 + j*(243) --69 + j*(88) --78 + j*(-173) -96 + j*(107) --100 + j*(178) --348 + j*(45) --27 + j*(30) -267 + j*(-211) -52 + j*(-66) -236 + j*(-195) -339 + j*(-69) -351 + j*(125) --79 + j*(-368) -71 + j*(4) --151 + j*(159) --47 + j*(-404) --266 + j*(209) -175 + j*(46) --301 + j*(-93) -281 + j*(-106) --25 + j*(-88) --96 + j*(-258) -160 + j*(-1) -128 + j*(28) -11 + j*(43) -137 + j*(412) --276 + j*(141) -64 + j*(-101) --82 + j*(-85) --194 + j*(100) --305 + j*(-136) -45 + j*(175) --28 + j*(-45) -190 + j*(169) -265 + j*(74) -264 + j*(-54) --26 + j*(112) --264 + j*(177) --255 + j*(320) -127 + j*(70) -184 + j*(-347) -132 + j*(244) -298 + j*(-8) --182 + j*(-144) --226 + j*(175) --40 + j*(323) -200 + j*(-257) --293 + j*(282) -11 + j*(-280) --1 + j*(-445) -18 + j*(-180) -134 + j*(10) --3 + j*(-98) -262 + j*(-4) -45 + j*(153) -376 + j*(84) --324 + j*(185) --197 + j*(-124) --152 + j*(-61) --40 + j*(-2) --173 + j*(-68) -98 + j*(108) -261 + j*(-73) -119 + j*(76) -28 + j*(-102) --305 + j*(-276) -243 + j*(180) --221 + j*(128) -64 + j*(-102) --108 + j*(267) --8 + j*(-108) --116 + j*(139) --91 + j*(-62) -24 + j*(25) --83 + j*(98) -45 + j*(-124) -173 + j*(47) --124 + j*(-233) --47 + j*(-125) --88 + j*(-132) --21 + j*(277) --112 + j*(-133) -88 + j*(97) --320 + j*(354) -338 + j*(259) --6 + j*(-208) --8 + j*(-50) -310 + j*(-15) --33 + j*(-134) -93 + j*(-54) -70 + j*(-214) -10 + j*(-65) -123 + j*(78) -317 + j*(147) --209 + j*(-153) -513 + j*(-206) --306 + j*(-128) -27 + j*(-395) -112 + j*(90) --17 + j*(35) --57 + j*(-4) --122 + j*(-385) -30 + j*(-61) --167 + j*(238) -269 + j*(265) -203 + j*(41) -253 + j*(70) -52 + j*(-152) --53 + j*(-49) -96 + j*(49) --202 + j*(-424) -34 + j*(-286) --505 + j*(-199) --190 + j*(166) -308 + j*(-265) --186 + j*(451) --331 + j*(-117) -115 + j*(64) --171 + j*(111) --106 + j*(266) -143 + j*(-148) --13 + j*(16) --168 + j*(375) -211 + j*(150) --470 + j*(104) --274 + j*(-323) -198 + j*(76) -115 + j*(349) --244 + j*(129) --5 + j*(-64) -309 + j*(-34) -18 + j*(107) -482 + j*(76) -136 + j*(245) --91 + j*(-34) --130 + j*(153) -83 + j*(-168) -0 + j*(-32) -23 + j*(-372) --44 + j*(-225) --228 + j*(-75) -28 + j*(244) --141 + j*(82) --149 + j*(-58) --271 + j*(-217) --331 + j*(270) --100 + j*(-6) -185 + j*(-83) -325 + j*(-273) -226 + j*(-206) -240 + j*(86) --154 + j*(-227) --48 + j*(-69) --42 + j*(72) -377 + j*(137) -62 + j*(-402) --53 + j*(-8) -29 + j*(63) --30 + j*(204) --255 + j*(390) -233 + j*(180) --53 + j*(-97) --42 + j*(-55) --32 + j*(-76) -66 + j*(410) -33 + j*(243) -163 + j*(-12) --195 + j*(-38) -254 + j*(98) --132 + j*(-132) -7 + j*(-87) -136 + j*(240) -59 + j*(42) -225 + j*(-68) --159 + j*(152) --129 + j*(-4) -269 + j*(-86) --37 + j*(79) --436 + j*(-71) --23 + j*(211) -163 + j*(176) --89 + j*(-98) --129 + j*(-387) -118 + j*(8) -38 + j*(-47) -337 + j*(-88) --4 + j*(-1) -231 + j*(-82) -54 + j*(366) --73 + j*(138) --8 + j*(-69) --163 + j*(135) --159 + j*(-257) --214 + j*(-268) --60 + j*(-36) -69 + j*(182) -172 + j*(115) --105 + j*(288) -77 + j*(-184) --107 + j*(101) -248 + j*(45) -61 + j*(-101) -292 + j*(-93) -69 + j*(-192) -143 + j*(66) --279 + j*(138) --74 + j*(-21) -371 + j*(-74) -134 + j*(300) --71 + j*(8) -108 + j*(-291) -4 + j*(129) --373 + j*(-51) -59 + j*(-117) -189 + j*(-206) -206 + j*(28) --242 + j*(-433) --98 + j*(-260) --102 + j*(169) --82 + j*(33) --11 + j*(-184) --24 + j*(-47) -77 + j*(-71) --117 + j*(-44) -204 + j*(-164) --10 + j*(-81) -179 + j*(-16) -68 + j*(-293) -22 + j*(37) -202 + j*(104) -30 + j*(45) -192 + j*(180) --136 + j*(-117) -120 + j*(173) --202 + j*(148) --172 + j*(173) --28 + j*(190) -115 + j*(-58) --167 + j*(199) --95 + j*(212) -168 + j*(-260) --250 + j*(-95) --35 + j*(100) --360 + j*(-88) --163 + j*(75) -335 + j*(-58) --14 + j*(151) --169 + j*(104) -334 + j*(105) --157 + j*(102) --45 + j*(316) --64 + j*(-126) --4 + j*(-431) --91 + j*(-217) -13 + j*(-134) -52 + j*(409) -160 + j*(14) -89 + j*(9) --217 + j*(5) --177 + j*(-442) -225 + j*(-34) --110 + j*(-98) -130 + j*(-428) --225 + j*(212) -44 + j*(-217) -40 + j*(-213) --158 + j*(30) -16 + j*(49) -101 + j*(-322) --93 + j*(38) -330 + j*(214) --61 + j*(18) -285 + j*(34) --228 + j*(-156) -146 + j*(83) --427 + j*(-93) --119 + j*(58) --91 + j*(-428) --177 + j*(-75) -62 + j*(-10) --29 + j*(-49) --76 + j*(95) -62 + j*(-320) --144 + j*(88) -197 + j*(-121) -243 + j*(-54) -113 + j*(223) -59 + j*(-157) -136 + j*(-99) -145 + j*(-90) --283 + j*(-42) --247 + j*(-106) -99 + j*(-380) --8 + j*(-124) --28 + j*(-31) -407 + j*(250) --198 + j*(-94) -244 + j*(154) -119 + j*(501) -82 + j*(315) -16 + j*(122) --6 + j*(-247) --162 + j*(300) -103 + j*(-98) -221 + j*(-177) --80 + j*(207) -43 + j*(105) -8 + j*(2) -251 + j*(-303) -143 + j*(-45) -209 + j*(-18) --35 + j*(76) --191 + j*(254) -178 + j*(-18) -66 + j*(-378) -45 + j*(-7) --159 + j*(-144) --282 + j*(-106) --225 + j*(2) --107 + j*(-255) -92 + j*(226) --39 + j*(-218) --102 + j*(139) -184 + j*(77) --78 + j*(134) -56 + j*(-278) --35 + j*(-81) --61 + j*(-204) --65 + j*(-25) --202 + j*(163) -310 + j*(-28) --111 + j*(-95) --2 + j*(141) --173 + j*(-51) --21 + j*(182) --257 + j*(-57) --83 + j*(81) --267 + j*(52) -2 + j*(13) -35 + j*(59) -105 + j*(190) --306 + j*(-253) -19 + j*(88) --3 + j*(-221) -234 + j*(-160) --9 + j*(-108) --325 + j*(356) --71 + j*(268) --308 + j*(364) --308 + j*(183) -193 + j*(-95) -62 + j*(-12) -107 + j*(42) --100 + j*(62) --84 + j*(57) --90 + j*(-427) --73 + j*(-35) --191 + j*(134) --48 + j*(-85) -193 + j*(-242) --80 + j*(61) -225 + j*(-24) --179 + j*(-218) -353 + j*(394) -197 + j*(109) -228 + j*(9) -386 + j*(167) -86 + j*(-8) -55 + j*(-312) --18 + j*(78) --32 + j*(-191) --24 + j*(20) -121 + j*(-126) --80 + j*(16) --161 + j*(367) --64 + j*(109) --22 + j*(37) --145 + j*(65) --197 + j*(-272) -103 + j*(-46) --98 + j*(99) --325 + j*(-251) -43 + j*(-93) --54 + j*(-3) -193 + j*(-82) -91 + j*(57) -80 + j*(-122) -151 + j*(-258) -36 + j*(-443) --69 + j*(-25) --116 + j*(-222) --12 + j*(-306) --298 + j*(-242) -243 + j*(-248) -94 + j*(-47) --65 + j*(103) --246 + j*(128) --27 + j*(52) --165 + j*(235) --88 + j*(41) --21 + j*(-100) --2 + j*(222) --156 + j*(163) -209 + j*(279) -55 + j*(177) --209 + j*(-136) -132 + j*(-42) --221 + j*(-51) -91 + j*(62) --34 + j*(129) --217 + j*(-257) -6 + j*(-36) --353 + j*(-90) --7 + j*(-86) -105 + j*(81) -148 + j*(-40) --20 + j*(-6) -93 + j*(-156) -145 + j*(120) --110 + j*(465) --39 + j*(23) --54 + j*(138) --69 + j*(87) --91 + j*(-74) -361 + j*(26) -513 + j*(-134) --293 + j*(-134) -18 + j*(-93) -424 + j*(177) --22 + j*(40) -173 + j*(74) -2 + j*(-207) --162 + j*(-165) -57 + j*(128) -315 + j*(80) --102 + j*(117) -238 + j*(-75) --107 + j*(134) --204 + j*(-153) --170 + j*(-9) -2 + j*(50) -88 + j*(110) --8 + j*(-115) --92 + j*(-237) --52 + j*(265) --40 + j*(16) --74 + j*(-80) --150 + j*(-26) --33 + j*(-29) -383 + j*(-48) --182 + j*(247) --192 + j*(260) -108 + j*(133) -175 + j*(-317) --12 + j*(-103) --24 + j*(-373) -141 + j*(-220) -170 + j*(-106) --112 + j*(-248) -180 + j*(-78) --252 + j*(-380) --39 + j*(-247) --152 + j*(39) -28 + j*(-119) --47 + j*(-174) -101 + j*(87) -127 + j*(77) -103 + j*(-255) -66 + j*(257) --105 + j*(32) -78 + j*(69) -26 + j*(-54) --31 + j*(73) -346 + j*(346) -8 + j*(26) --37 + j*(-59) -21 + j*(194) --28 + j*(183) -100 + j*(-55) --157 + j*(175) --322 + j*(-137) --33 + j*(132) --477 + j*(-62) -332 + j*(-111) -83 + j*(282) --134 + j*(92) --269 + j*(-296) --4 + j*(5) -69 + j*(-35) --299 + j*(14) -154 + j*(-176) --137 + j*(11) -156 + j*(-180) --66 + j*(-36) --10 + j*(57) --261 + j*(-361) --36 + j*(74) --31 + j*(147) --19 + j*(-169) -149 + j*(256) --332 + j*(29) --293 + j*(-197) -117 + j*(-184) -235 + j*(134) -251 + j*(86) -54 + j*(-310) -13 + j*(-11) --385 + j*(-286) --2 + j*(-37) --115 + j*(-48) -197 + j*(-20) -264 + j*(136) --243 + j*(-59) --187 + j*(30) -92 + j*(28) --91 + j*(-238) --93 + j*(-179) -6 + j*(76) -11 + j*(6) --96 + j*(78) -25 + j*(59) -110 + j*(523) -141 + j*(-14) --94 + j*(-10) -22 + j*(-120) -443 + j*(-14) -95 + j*(-174) --141 + j*(125) --12 + j*(-354) --193 + j*(-144) --156 + j*(-74) -210 + j*(317) -281 + j*(-52) -77 + j*(89) -21 + j*(-80) -332 + j*(-6) -292 + j*(18) -57 + j*(-45) --65 + j*(113) --317 + j*(-109) --378 + j*(-298) -185 + j*(1) --453 + j*(-45) -123 + j*(279) -27 + j*(57) --299 + j*(23) -112 + j*(47) --47 + j*(174) -33 + j*(-227) --288 + j*(9) --153 + j*(5) -250 + j*(52) --119 + j*(-208) -127 + j*(262) --30 + j*(-109) -55 + j*(-247) --112 + j*(-44) --82 + j*(-38) --297 + j*(-16) -59 + j*(60) --198 + j*(-55) -204 + j*(-151) -12 + j*(40) --627 + j*(-236) --112 + j*(-281) --91 + j*(-167) -38 + j*(83) --146 + j*(130) --228 + j*(29) --67 + j*(-216) -100 + j*(30) -137 + j*(190) -173 + j*(337) -252 + j*(-108) -431 + j*(-163) -217 + j*(-54) --156 + j*(-250) -286 + j*(-232) -286 + j*(-181) --103 + j*(-117) --177 + j*(81) --246 + j*(-159) --254 + j*(58) -69 + j*(157) --110 + j*(34) -262 + j*(95) --130 + j*(148) -144 + j*(345) -152 + j*(25) -89 + j*(236) -257 + j*(146) -50 + j*(-297) -109 + j*(207) -105 + j*(-262) -330 + j*(-397) --221 + j*(-162) -60 + j*(-54) -49 + j*(-194) -24 + j*(-104) --45 + j*(-18) --180 + j*(266) --25 + j*(183) -64 + j*(221) -302 + j*(409) --55 + j*(3) -226 + j*(-310) -37 + j*(-49) --116 + j*(66) -115 + j*(-84) --155 + j*(174) --134 + j*(100) --211 + j*(-69) -226 + j*(-11) -397 + j*(43) -170 + j*(81) --107 + j*(-122) -433 + j*(-25) -115 + j*(-77) --235 + j*(-4) --308 + j*(-138) -187 + j*(241) -49 + j*(8) -62 + j*(105) --296 + j*(122) -33 + j*(497) -334 + j*(-1) -194 + j*(41) -204 + j*(-245) --49 + j*(15) --103 + j*(16) --217 + j*(56) -28 + j*(196) -343 + j*(-173) -173 + j*(164) --100 + j*(167) --94 + j*(-25) --79 + j*(-95) -30 + j*(-276) -144 + j*(61) --120 + j*(-195) --213 + j*(-366) -209 + j*(30) -6 + j*(-245) --43 + j*(-83) -28 + j*(61) -4 + j*(-51) --167 + j*(52) --245 + j*(4) --48 + j*(-92) --53 + j*(210) --156 + j*(-160) --82 + j*(-115) --198 + j*(-206) --134 + j*(-6) -203 + j*(-311) --317 + j*(-81) --66 + j*(-54) -67 + j*(-153) --34 + j*(-26) --14 + j*(-69) -91 + j*(163) --6 + j*(-6) --141 + j*(66) --91 + j*(241) --42 + j*(196) --49 + j*(-35) --175 + j*(-137) -16 + j*(267) -49 + j*(-106) -45 + j*(97) --351 + j*(119) --276 + j*(-46) --109 + j*(94) -3 + j*(170) --182 + j*(323) -97 + j*(-124) --203 + j*(307) --233 + j*(231) --134 + j*(78) -282 + j*(8) -124 + j*(319) -119 + j*(-40) --176 + j*(-145) -26 + j*(42) -97 + j*(-273) --319 + j*(-56) --148 + j*(-65) --12 + j*(242) -16 + j*(165) -264 + j*(85) --181 + j*(-34) -1 + j*(-103) -194 + j*(-12) -14 + j*(260) --251 + j*(-40) --280 + j*(81) --42 + j*(-2) --6 + j*(152) -155 + j*(245) --267 + j*(103) --23 + j*(-334) --177 + j*(100) -8 + j*(-99) -104 + j*(-202) -168 + j*(94) -59 + j*(-193) -57 + j*(116) -98 + j*(-116) --96 + j*(-264) --44 + j*(301) -138 + j*(6) --168 + j*(187) --306 + j*(-88) --163 + j*(-206) --222 + j*(52) -319 + j*(32) -45 + j*(-178) --207 + j*(-179) -160 + j*(-24) -84 + j*(460) -91 + j*(-168) -168 + j*(119) -11 + j*(-8) --145 + j*(195) --145 + j*(-81) -39 + j*(247) --66 + j*(203) -208 + j*(-63) -167 + j*(40) --64 + j*(366) -51 + j*(262) -21 + j*(139) --38 + j*(-226) -158 + j*(-107) --109 + j*(566) -100 + j*(-16) -2 + j*(43) -1 + j*(-100) -23 + j*(-98) --48 + j*(-217) --64 + j*(218) -105 + j*(-83) --186 + j*(104) --64 + j*(-268) -1 + j*(131) --219 + j*(-175) --100 + j*(69) -34 + j*(-469) -199 + j*(177) -305 + j*(-176) --184 + j*(-29) --332 + j*(50) -309 + j*(93) --19 + j*(-73) --21 + j*(-3) -56 + j*(81) -171 + j*(-164) -62 + j*(-228) --21 + j*(-373) --88 + j*(-193) -201 + j*(-6) -340 + j*(-322) -207 + j*(7) --89 + j*(-211) --206 + j*(12) --161 + j*(-84) -49 + j*(-272) -132 + j*(-129) --126 + j*(304) -26 + j*(66) --39 + j*(84) --228 + j*(-138) -71 + j*(13) --27 + j*(-319) -157 + j*(104) -98 + j*(291) -187 + j*(-319) -287 + j*(52) --91 + j*(228) --42 + j*(-133) -297 + j*(-35) -28 + j*(-127) -50 + j*(38) -253 + j*(-35) -126 + j*(-69) -153 + j*(-41) --141 + j*(203) --63 + j*(-108) --69 + j*(-134) -274 + j*(273) -255 + j*(-329) -202 + j*(31) --158 + j*(-15) -240 + j*(122) --249 + j*(205) --29 + j*(171) --209 + j*(28) -146 + j*(-77) -124 + j*(-155) --21 + j*(-257) -342 + j*(292) --75 + j*(145) --37 + j*(199) -124 + j*(317) -198 + j*(48) -197 + j*(35) --71 + j*(-55) -235 + j*(-358) --136 + j*(62) --121 + j*(-194) --129 + j*(190) -126 + j*(160) -153 + j*(154) -223 + j*(-95) -78 + j*(-270) -447 + j*(60) --184 + j*(-173) --121 + j*(-134) -141 + j*(-25) -179 + j*(-190) -26 + j*(305) --180 + j*(-13) -123 + j*(-4) -130 + j*(-310) --42 + j*(-91) -71 + j*(286) --192 + j*(33) -130 + j*(206) -147 + j*(2) --38 + j*(-156) -1 + j*(327) --34 + j*(-42) --254 + j*(-168) -189 + j*(227) -143 + j*(32) --211 + j*(-264) --39 + j*(-439) --24 + j*(271) --25 + j*(110) -190 + j*(-4) --102 + j*(-243) --13 + j*(40) --87 + j*(55) -156 + j*(89) -295 + j*(-50) -210 + j*(-263) --303 + j*(70) -86 + j*(-102) --68 + j*(4) -79 + j*(-426) --152 + j*(-158) -93 + j*(36) -52 + j*(-144) -27 + j*(-280) -58 + j*(-16) -82 + j*(2) -57 + j*(-151) --76 + j*(-21) --67 + j*(125) -233 + j*(-44) -72 + j*(-83) -203 + j*(52) --35 + j*(0) -140 + j*(-147) -110 + j*(144) -96 + j*(23) -288 + j*(-122) --67 + j*(85) -300 + j*(-56) --262 + j*(39) -201 + j*(233) --20 + j*(151) --323 + j*(-35) -49 + j*(143) --89 + j*(-158) --66 + j*(-216) --244 + j*(163) -240 + j*(-245) -364 + j*(-71) --205 + j*(280) -66 + j*(-18) --58 + j*(144) -141 + j*(-151) -154 + j*(-25) -202 + j*(-83) -33 + j*(-127) --166 + j*(-157) -451 + j*(-244) --101 + j*(35) -18 + j*(134) -134 + j*(252) --95 + j*(-264) -320 + j*(211) --54 + j*(-52) --145 + j*(122) --10 + j*(247) --359 + j*(164) --93 + j*(-90) --141 + j*(199) --122 + j*(-140) --384 + j*(-230) -34 + j*(2) --190 + j*(276) --49 + j*(185) -197 + j*(-12) --213 + j*(-105) --110 + j*(-62) --1 + j*(163) -54 + j*(12) -74 + j*(-148) --130 + j*(221) --86 + j*(161) -86 + j*(50) --110 + j*(-74) -129 + j*(256) -25 + j*(-84) --35 + j*(-124) -71 + j*(-105) -274 + j*(-267) -298 + j*(-52) --1 + j*(116) -220 + j*(-17) -147 + j*(126) -69 + j*(53) --208 + j*(-60) -197 + j*(115) --140 + j*(13) -122 + j*(-74) -36 + j*(194) --40 + j*(-26) --126 + j*(97) -288 + j*(115) --142 + j*(127) --20 + j*(-21) --117 + j*(79) --73 + j*(308) --430 + j*(132) --129 + j*(161) -83 + j*(56) --63 + j*(-355) --139 + j*(132) -206 + j*(8) -19 + j*(-193) -156 + j*(-25) -20 + j*(-277) -74 + j*(207) --312 + j*(-97) --264 + j*(127) -219 + j*(69) --16 + j*(126) -92 + j*(-206) --227 + j*(164) --172 + j*(-120) -158 + j*(-31) -110 + j*(83) --103 + j*(6) --22 + j*(120) -110 + j*(93) -37 + j*(-170) --148 + j*(136) --23 + j*(12) -59 + j*(61) -117 + j*(119) -163 + j*(283) -263 + j*(95) -334 + j*(65) --169 + j*(80) --129 + j*(543) --163 + j*(179) -46 + j*(193) --177 + j*(232) -206 + j*(13) -203 + j*(67) -42 + j*(31) -119 + j*(-159) --98 + j*(104) -68 + j*(70) -91 + j*(155) -55 + j*(-175) -88 + j*(-54) --148 + j*(-14) -405 + j*(30) -250 + j*(-249) -6 + j*(234) -71 + j*(69) -57 + j*(-92) -194 + j*(44) --104 + j*(175) -136 + j*(-145) -137 + j*(-80) -110 + j*(-363) -240 + j*(-14) --110 + j*(158) --57 + j*(28) --112 + j*(-86) -25 + j*(192) -139 + j*(-252) --250 + j*(-42) -25 + j*(61) --235 + j*(-152) -310 + j*(-206) --341 + j*(-164) --113 + j*(4) --62 + j*(-13) -216 + j*(90) --45 + j*(-161) --129 + j*(-240) -124 + j*(173) -66 + j*(180) -80 + j*(-23) --62 + j*(144) -28 + j*(-5) -115 + j*(184) -75 + j*(-197) --325 + j*(100) -94 + j*(-126) --78 + j*(-344) --107 + j*(302) --243 + j*(-243) -62 + j*(227) --15 + j*(-337) --49 + j*(-74) -88 + j*(134) --91 + j*(81) --34 + j*(103) --112 + j*(233) -253 + j*(151) --45 + j*(-25) -212 + j*(-127) --363 + j*(66) -251 + j*(12) -267 + j*(27) -280 + j*(-414) -136 + j*(131) --32 + j*(-176) -136 + j*(31) --139 + j*(171) -185 + j*(103) -84 + j*(198) -88 + j*(81) -104 + j*(-158) -301 + j*(298) -63 + j*(260) -210 + j*(-169) -112 + j*(-52) --64 + j*(119) --169 + j*(-281) --83 + j*(-310) -274 + j*(-79) -209 + j*(-182) --107 + j*(-240) --86 + j*(4) -202 + j*(16) --387 + j*(75) --81 + j*(85) -17 + j*(260) --348 + j*(-243) --39 + j*(88) -259 + j*(-40) -37 + j*(13) -157 + j*(-121) -40 + j*(-37) -267 + j*(-28) -85 + j*(47) --310 + j*(52) -25 + j*(33) --366 + j*(-264) --58 + j*(120) -36 + j*(-93) -187 + j*(6) -93 + j*(23) -44 + j*(-240) -235 + j*(161) -197 + j*(293) --153 + j*(126) -211 + j*(-71) -213 + j*(-42) -176 + j*(-6) --176 + j*(-40) -33 + j*(64) --81 + j*(-133) -52 + j*(256) -160 + j*(-141) -118 + j*(187) --212 + j*(26) --257 + j*(157) -192 + j*(18) -199 + j*(295) -49 + j*(-94) -2 + j*(208) --83 + j*(-170) --226 + j*(-139) --197 + j*(18) -40 + j*(-130) -144 + j*(-136) -107 + j*(19) --102 + j*(472) --53 + j*(-39) -5 + j*(265) -173 + j*(256) --349 + j*(40) -54 + j*(-140) -66 + j*(132) -64 + j*(73) --141 + j*(95) -327 + j*(-69) --547 + j*(115) -59 + j*(-115) --62 + j*(69) -81 + j*(182) --86 + j*(-208) --100 + j*(-318) -127 + j*(213) -93 + j*(16) -243 + j*(-7) --23 + j*(333) --21 + j*(330) -74 + j*(-50) --40 + j*(-168) -434 + j*(333) -81 + j*(-143) -230 + j*(163) -209 + j*(-187) --33 + j*(270) -132 + j*(-217) --127 + j*(-35) --59 + j*(40) -187 + j*(32) --11 + j*(-143) -156 + j*(245) --18 + j*(-28) --166 + j*(-27) -332 + j*(145) -8 + j*(-192) --11 + j*(-185) --190 + j*(72) --118 + j*(138) -112 + j*(215) --26 + j*(52) -137 + j*(29) --200 + j*(-123) -183 + j*(-187) -93 + j*(35) --336 + j*(-33) -28 + j*(223) --1 + j*(-18) --234 + j*(98) -117 + j*(25) -132 + j*(-174) --430 + j*(-3) -52 + j*(-205) -95 + j*(148) --55 + j*(-199) -20 + j*(-107) --113 + j*(-80) -51 + j*(26) --13 + j*(79) --182 + j*(20) --71 + j*(-19) --16 + j*(-290) --197 + j*(204) -42 + j*(-184) --63 + j*(52) -16 + j*(-112) -164 + j*(-293) --39 + j*(113) -267 + j*(-49) -259 + j*(-80) --65 + j*(55) -151 + j*(112) --21 + j*(113) -64 + j*(-163) -71 + j*(28) -155 + j*(126) -226 + j*(47) -173 + j*(195) -11 + j*(-218) -87 + j*(-64) -126 + j*(-53) -34 + j*(-310) -225 + j*(-183) --148 + j*(-328) -210 + j*(-400) -289 + j*(49) -3 + j*(-170) -231 + j*(54) -136 + j*(21) --83 + j*(273) -108 + j*(251) -429 + j*(277) -6 + j*(294) -103 + j*(207) -16 + j*(-199) -187 + j*(28) -16 + j*(51) -232 + j*(51) --148 + j*(9) -77 + j*(-168) -42 + j*(279) -132 + j*(265) -145 + j*(-90) --49 + j*(-211) -90 + j*(144) -156 + j*(3) -27 + j*(-264) -302 + j*(23) -148 + j*(-5) --119 + j*(-27) --100 + j*(-138) --182 + j*(-56) --303 + j*(333) --101 + j*(162) -311 + j*(-143) --27 + j*(-283) --215 + j*(-93) --64 + j*(120) --10 + j*(-337) --204 + j*(48) --91 + j*(-95) -113 + j*(-223) --68 + j*(-86) -91 + j*(-162) -383 + j*(534) -331 + j*(-151) -296 + j*(-125) --534 + j*(195) -68 + j*(341) --64 + j*(338) -202 + j*(199) -277 + j*(-187) -10 + j*(-149) --89 + j*(-287) -356 + j*(-535) -136 + j*(225) -221 + j*(-13) -245 + j*(105) --55 + j*(-260) --246 + j*(-332) --146 + j*(315) --602 + j*(-237) --329 + j*(238) --173 + j*(-174) -562 + j*(83) --189 + j*(-310) -339 + j*(361) --309 + j*(-162) -81 + j*(317) -445 + j*(-265) --183 + j*(343) --302 + j*(33) --663 + j*(180) --257 + j*(-70) -515 + j*(252) -192 + j*(334) --560 + j*(68) -214 + j*(11) --463 + j*(-437) -66 + j*(286) --305 + j*(236) --332 + j*(40) --180 + j*(-321) -420 + j*(-76) -63 + j*(-168) -243 + j*(-251) -176 + j*(-378) -328 + j*(303) --270 + j*(353) --407 + j*(-240) -257 + j*(207) --107 + j*(-203) --100 + j*(-153) -635 + j*(335) -45 + j*(52) -251 + j*(-25) -238 + j*(232) --268 + j*(-144) -183 + j*(-70) --237 + j*(-222) -231 + j*(274) --132 + j*(372) -383 + j*(50) --187 + j*(195) -81 + j*(156) --145 + j*(-689) -139 + j*(312) --162 + j*(419) -387 + j*(-187) --168 + j*(-233) --344 + j*(184) --337 + j*(-478) -737 + j*(-88) --106 + j*(486) -44 + j*(226) --293 + j*(100) -532 + j*(-33) -534 + j*(-52) --527 + j*(431) --438 + j*(-312) -223 + j*(-175) -149 + j*(367) -132 + j*(-694) -406 + j*(306) -222 + j*(-339) --68 + j*(493) -348 + j*(123) -16 + j*(-402) -125 + j*(-231) --468 + j*(-245) -304 + j*(74) -439 + j*(423) --438 + j*(18) --686 + j*(327) --150 + j*(98) -303 + j*(147) -411 + j*(-9) --298 + j*(103) --185 + j*(-97) --288 + j*(-369) -393 + j*(-370) -491 + j*(433) -412 + j*(146) --167 + j*(-435) -199 + j*(-350) -316 + j*(-90) -204 + j*(-154) --333 + j*(-12) -682 + j*(-197) --139 + j*(439) --306 + j*(49) --281 + j*(-679) -454 + j*(-212) -444 + j*(508) -106 + j*(-67) --122 + j*(-80) -268 + j*(196) -587 + j*(-342) --275 + j*(379) -443 + j*(-190) --606 + j*(199) --108 + j*(524) --202 + j*(201) --395 + j*(-388) -511 + j*(-591) --265 + j*(-98) -224 + j*(189) -231 + j*(-250) -45 + j*(-397) --286 + j*(-167) -230 + j*(40) -346 + j*(395) --400 + j*(635) -43 + j*(-228) -397 + j*(149) --160 + j*(520) -204 + j*(213) -335 + j*(398) -344 + j*(504) --11 + j*(-309) -59 + j*(-37) --390 + j*(-374) --361 + j*(518) -386 + j*(131) -233 + j*(-187) -356 + j*(23) --157 + j*(-261) --451 + j*(-523) -167 + j*(593) -209 + j*(119) --730 + j*(-56) --219 + j*(-598) -29 + j*(250) -79 + j*(392) -300 + j*(158) -276 + j*(-165) -72 + j*(-346) --245 + j*(-170) -455 + j*(-394) -48 + j*(315) -33 + j*(-81) -201 + j*(127) --37 + j*(51) -196 + j*(180) --62 + j*(416) -267 + j*(252) --242 + j*(-452) --8 + j*(397) -124 + j*(40) --264 + j*(-126) -42 + j*(404) -558 + j*(103) --327 + j*(35) --510 + j*(528) --561 + j*(-597) --349 + j*(-397) -41 + j*(214) --334 + j*(462) -98 + j*(-105) --75 + j*(229) -245 + j*(-116) -330 + j*(186) --81 + j*(434) -488 + j*(200) --124 + j*(-164) --8 + j*(68) --88 + j*(373) --312 + j*(-402) -103 + j*(267) -683 + j*(217) --341 + j*(67) --280 + j*(350) -492 + j*(-231) --211 + j*(-218) -240 + j*(316) -364 + j*(272) -370 + j*(453) -253 + j*(171) -184 + j*(663) --333 + j*(-392) --192 + j*(-409) -384 + j*(-292) -220 + j*(-143) --284 + j*(242) -118 + j*(-272) -170 + j*(-47) -422 + j*(-353) -494 + j*(-685) --88 + j*(95) -264 + j*(232) -153 + j*(175) -168 + j*(205) --126 + j*(-213) --51 + j*(390) --283 + j*(40) --361 + j*(689) -171 + j*(-141) -435 + j*(-318) --141 + j*(-260) -220 + j*(-144) -286 + j*(155) --310 + j*(299) -78 + j*(-204) -373 + j*(273) --321 + j*(723) -707 + j*(-203) -324 + j*(102) --177 + j*(-383) -245 + j*(-99) --380 + j*(339) -235 + j*(-375) --292 + j*(77) -23 + j*(-351) -330 + j*(-171) -211 + j*(167) -455 + j*(-540) --448 + j*(-230) -215 + j*(263) -137 + j*(373) --66 + j*(-47) --300 + j*(-85) -302 + j*(177) --442 + j*(197) --46 + j*(132) --419 + j*(214) --166 + j*(92) --184 + j*(447) -94 + j*(342) --328 + j*(-42) --552 + j*(-458) -374 + j*(-177) -300 + j*(404) -40 + j*(219) --228 + j*(-505) -272 + j*(266) --192 + j*(200) -213 + j*(-150) -274 + j*(-355) -492 + j*(54) -541 + j*(-602) -460 + j*(-52) -98 + j*(449) -382 + j*(-380) --153 + j*(-241) --250 + j*(-45) --245 + j*(-315) -264 + j*(-289) -154 + j*(-177) -146 + j*(-441) --336 + j*(285) --102 + j*(388) -236 + j*(-18) --115 + j*(335) --532 + j*(421) -484 + j*(450) -354 + j*(738) --416 + j*(523) --293 + j*(-193) -115 + j*(-764) --327 + j*(-238) --425 + j*(-378) --269 + j*(-413) --642 + j*(-380) --43 + j*(-7) -206 + j*(424) -244 + j*(-416) -453 + j*(-545) --165 + j*(-64) --138 + j*(-312) --499 + j*(484) --307 + j*(-119) -122 + j*(578) --266 + j*(-390) --218 + j*(395) --188 + j*(-14) -373 + j*(-118) -86 + j*(629) --435 + j*(-107) -390 + j*(-469) -197 + j*(-99) -343 + j*(-344) --137 + j*(-218) --252 + j*(354) --261 + j*(329) --214 + j*(393) --247 + j*(274) -214 + j*(158) -74 + j*(315) -434 + j*(-211) --228 + j*(-161) --86 + j*(482) -41 + j*(197) --110 + j*(217) -182 + j*(16) -437 + j*(-583) -446 + j*(-162) --139 + j*(122) -117 + j*(368) -173 + j*(179) -245 + j*(-228) -78 + j*(450) --484 + j*(-112) --375 + j*(-177) --265 + j*(-155) -185 + j*(-10) -635 + j*(-213) --59 + j*(223) -306 + j*(-93) -8 + j*(-310) -201 + j*(333) -482 + j*(-70) --78 + j*(115) -390 + j*(564) -433 + j*(280) -52 + j*(25) -185 + j*(328) -273 + j*(-367) --156 + j*(255) -177 + j*(-170) --181 + j*(207) --466 + j*(-256) --279 + j*(-97) -444 + j*(-466) --105 + j*(308) -71 + j*(-127) --1 + j*(6) -171 + j*(163) --357 + j*(440) -346 + j*(97) --366 + j*(-355) --149 + j*(-342) --72 + j*(-146) -120 + j*(185) -190 + j*(237) --53 + j*(-444) -340 + j*(68) -103 + j*(7) -210 + j*(183) -282 + j*(-173) -240 + j*(373) --112 + j*(463) --187 + j*(262) --260 + j*(-234) --33 + j*(217) --347 + j*(2) -229 + j*(-414) -163 + j*(284) -121 + j*(61) --286 + j*(439) -403 + j*(112) --290 + j*(122) -339 + j*(151) -339 + j*(-290) -349 + j*(-248) --403 + j*(315) --318 + j*(-601) --293 + j*(-348) -279 + j*(-15) -79 + j*(-222) --458 + j*(-433) -625 + j*(-496) --81 + j*(204) --222 + j*(-499) --486 + j*(-186) --113 + j*(-105) --199 + j*(-497) -351 + j*(174) -347 + j*(-373) -233 + j*(49) --64 + j*(-416) -264 + j*(-139) -33 + j*(494) -281 + j*(180) --412 + j*(-375) --318 + j*(502) --265 + j*(274) --260 + j*(175) -167 + j*(-491) -647 + j*(236) --25 + j*(238) --326 + j*(-495) -100 + j*(-313) -173 + j*(-786) --98 + j*(231) --238 + j*(409) -361 + j*(-446) -538 + j*(-350) --127 + j*(-153) --576 + j*(-199) --72 + j*(-510) -363 + j*(-360) --482 + j*(-238) --352 + j*(-363) --295 + j*(-104) --119 + j*(212) -297 + j*(351) --268 + j*(-371) -97 + j*(53) -235 + j*(90) -209 + j*(298) --212 + j*(-276) --309 + j*(551) --54 + j*(-273) -225 + j*(457) -37 + j*(-149) --81 + j*(202) -345 + j*(300) --322 + j*(247) -202 + j*(425) --215 + j*(-173) --123 + j*(297) --227 + j*(19) --170 + j*(-366) -344 + j*(-305) -369 + j*(-191) --318 + j*(525) -332 + j*(-325) --337 + j*(-318) --655 + j*(564) -595 + j*(-511) -436 + j*(384) --515 + j*(40) -243 + j*(-459) --21 + j*(156) -258 + j*(-438) --357 + j*(-326) --433 + j*(583) --357 + j*(-489) -171 + j*(-34) -122 + j*(402) --289 + j*(339) -160 + j*(189) -94 + j*(-71) -453 + j*(-301) -292 + j*(-117) -338 + j*(216) -363 + j*(400) --43 + j*(-35) -217 + j*(85) -33 + j*(241) -173 + j*(-141) --266 + j*(-306) --264 + j*(-451) -226 + j*(-296) -350 + j*(-16) -30 + j*(312) --566 + j*(-133) --195 + j*(219) -478 + j*(-61) --612 + j*(-527) --189 + j*(-585) --466 + j*(-600) --288 + j*(445) --460 + j*(245) -171 + j*(-448) --258 + j*(520) --379 + j*(-194) -369 + j*(-410) --213 + j*(144) -128 + j*(-40) -308 + j*(277) --37 + j*(-508) -226 + j*(-127) -290 + j*(285) --506 + j*(-353) --356 + j*(-194) -298 + j*(307) -161 + j*(499) -267 + j*(157) -117 + j*(-136) -494 + j*(-658) -103 + j*(-286) -415 + j*(465) -233 + j*(-156) -110 + j*(-371) --428 + j*(196) --377 + j*(269) --234 + j*(127) --321 + j*(-78) -282 + j*(-223) --310 + j*(-246) -45 + j*(146) -5 + j*(38) --182 + j*(239) --430 + j*(453) -414 + j*(-105) --527 + j*(147) --12 + j*(554) --296 + j*(-168) --147 + j*(-170) --504 + j*(-331) --313 + j*(-380) -453 + j*(429) --463 + j*(-119) --175 + j*(-387) -251 + j*(403) --143 + j*(187) -208 + j*(-498) -434 + j*(-214) -600 + j*(-360) --251 + j*(28) -373 + j*(-204) --305 + j*(-288) --243 + j*(356) -53 + j*(-467) -127 + j*(226) --412 + j*(-91) -325 + j*(371) -347 + j*(-487) -332 + j*(327) --226 + j*(-306) -482 + j*(-47) --62 + j*(397) -363 + j*(-184) -192 + j*(257) --390 + j*(-347) --15 + j*(-159) -434 + j*(-467) -347 + j*(-162) -374 + j*(-216) --197 + j*(-21) -195 + j*(679) -317 + j*(451) -206 + j*(400) -420 + j*(421) --190 + j*(-107) --141 + j*(192) -452 + j*(364) --550 + j*(44) --141 + j*(-274) --459 + j*(409) -466 + j*(-351) --178 + j*(103) --378 + j*(351) --213 + j*(132) --322 + j*(102) --244 + j*(-537) --252 + j*(-467) --266 + j*(483) -433 + j*(-273) --180 + j*(-474) -69 + j*(-356) -412 + j*(-295) --36 + j*(-529) --588 + j*(194) --10 + j*(-25) --446 + j*(-204) --380 + j*(1) --481 + j*(-128) --271 + j*(151) --303 + j*(-184) -272 + j*(-253) -102 + j*(284) --153 + j*(66) -100 + j*(-302) -385 + j*(-581) -259 + j*(605) -205 + j*(-482) --288 + j*(-276) -197 + j*(-288) --398 + j*(325) -358 + j*(-357) -104 + j*(-474) -735 + j*(38) -306 + j*(-162) -121 + j*(-267) --480 + j*(272) --13 + j*(-94) --146 + j*(131) --484 + j*(-257) --64 + j*(227) -178 + j*(19) -212 + j*(450) -17 + j*(-184) --406 + j*(-301) --424 + j*(252) --194 + j*(444) --550 + j*(-138) -361 + j*(424) --308 + j*(-156) --251 + j*(-183) -293 + j*(-98) --271 + j*(249) --317 + j*(-79) --42 + j*(276) --88 + j*(217) -1 + j*(327) --53 + j*(250) --42 + j*(-334) -154 + j*(70) -262 + j*(-33) --1 + j*(-104) -35 + j*(-118) -57 + j*(455) -247 + j*(-148) -0 + j*(62) --200 + j*(193) -62 + j*(-139) -95 + j*(111) -291 + j*(-154) --135 + j*(118) -66 + j*(-148) --337 + j*(192) --247 + j*(-26) --13 + j*(-40) --412 + j*(-91) --66 + j*(-206) -91 + j*(179) --189 + j*(407) --152 + j*(35) -187 + j*(28) -206 + j*(7) -242 + j*(-28) --71 + j*(-75) --187 + j*(-48) -240 + j*(-105) --122 + j*(-187) --156 + j*(163) -225 + j*(102) -52 + j*(198) --62 + j*(3) -171 + j*(-147) --84 + j*(-253) --1 + j*(-402) -264 + j*(140) --2 + j*(-152) -75 + j*(-168) --134 + j*(-34) -45 + j*(155) --164 + j*(135) -334 + j*(281) --71 + j*(-170) -296 + j*(-413) -44 + j*(260) -197 + j*(204) -71 + j*(2) -119 + j*(-129) -169 + j*(68) --196 + j*(198) -170 + j*(-124) --120 + j*(-8) -102 + j*(-120) --578 + j*(93) -71 + j*(239) --218 + j*(91) --206 + j*(9) --287 + j*(-461) --260 + j*(-65) -28 + j*(-45) --26 + j*(132) --86 + j*(-8) -0 + j*(-16) --86 + j*(499) --49 + j*(352) -14 + j*(108) -299 + j*(-55) --255 + j*(-81) --375 + j*(228) --125 + j*(66) --107 + j*(159) --199 + j*(-283) -158 + j*(-206) -241 + j*(-91) --44 + j*(4) --288 + j*(127) --19 + j*(-119) -83 + j*(-223) -76 + j*(-191) --19 + j*(64) -205 + j*(-267) -209 + j*(100) -290 + j*(175) -96 + j*(12) -71 + j*(15) -231 + j*(70) -127 + j*(-37) --153 + j*(195) -29 + j*(189) --30 + j*(-94) --55 + j*(-209) -338 + j*(-214) -122 + j*(-64) --234 + j*(172) -160 + j*(-110) -142 + j*(114) -157 + j*(136) --189 + j*(-197) -28 + j*(-45) --42 + j*(-143) -171 + j*(-12) --168 + j*(163) --199 + j*(194) --265 + j*(-212) -181 + j*(-21) --267 + j*(-224) --191 + j*(110) --77 + j*(-215) -83 + j*(-106) --52 + j*(451) --60 + j*(92) --171 + j*(-199) -233 + j*(-231) --107 + j*(39) -151 + j*(42) -120 + j*(-6) --257 + j*(-182) -110 + j*(-52) --208 + j*(-26) --130 + j*(-157) -153 + j*(267) -494 + j*(-45) -178 + j*(-91) --59 + j*(-184) -137 + j*(318) --315 + j*(254) --264 + j*(-67) -42 + j*(-4) -102 + j*(62) --43 + j*(-23) --132 + j*(79) --163 + j*(-138) --132 + j*(-232) -106 + j*(50) -264 + j*(56) --172 + j*(-100) -318 + j*(147) -84 + j*(-246) -274 + j*(-330) -177 + j*(19) -185 + j*(81) -201 + j*(18) --306 + j*(110) -81 + j*(-6) -65 + j*(-186) --278 + j*(-66) -175 + j*(55) -8 + j*(107) --85 + j*(14) -300 + j*(395) --65 + j*(-403) -293 + j*(-56) --187 + j*(103) -66 + j*(-240) -66 + j*(-302) --82 + j*(-214) -194 + j*(-47) -64 + j*(-235) --372 + j*(-222) -119 + j*(-341) --323 + j*(40) --114 + j*(293) --208 + j*(-158) --95 + j*(183) -161 + j*(231) -47 + j*(-131) -102 + j*(-31) -205 + j*(-180) --40 + j*(-127) -175 + j*(-288) -79 + j*(-272) --245 + j*(3) -251 + j*(-3) --119 + j*(243) --123 + j*(-339) --290 + j*(85) --100 + j*(-175) --205 + j*(477) --24 + j*(-71) -342 + j*(-185) -66 + j*(13) --56 + j*(78) -175 + j*(-124) --228 + j*(117) --122 + j*(-62) -72 + j*(308) -222 + j*(-223) -85 + j*(47) --59 + j*(173) --97 + j*(142) -141 + j*(-108) --278 + j*(107) --141 + j*(75) -211 + j*(74) -319 + j*(-107) --98 + j*(209) --350 + j*(45) --468 + j*(-308) -332 + j*(-157) --10 + j*(-57) -21 + j*(-37) -1 + j*(-71) -151 + j*(18) --356 + j*(361) -7 + j*(-8) --87 + j*(-148) -205 + j*(-86) --9 + j*(85) -419 + j*(64) -80 + j*(60) -199 + j*(197) --187 + j*(-205) --119 + j*(228) -11 + j*(187) --212 + j*(-21) --160 + j*(121) -45 + j*(-420) --158 + j*(-173) -49 + j*(286) -204 + j*(54) -158 + j*(206) --1 + j*(-63) -119 + j*(9) -169 + j*(-116) -325 + j*(145) --106 + j*(6) --96 + j*(44) --140 + j*(253) -138 + j*(23) --431 + j*(-37) --72 + j*(5) --35 + j*(128) --165 + j*(75) --45 + j*(-158) -298 + j*(119) -105 + j*(119) -162 + j*(-16) -64 + j*(-173) --269 + j*(37) -110 + j*(-21) --16 + j*(30) -113 + j*(129) --164 + j*(-238) --189 + j*(62) -66 + j*(-142) -418 + j*(20) --264 + j*(-245) --251 + j*(76) -24 + j*(-4) -310 + j*(-84) --112 + j*(-76) --20 + j*(27) -270 + j*(-126) --241 + j*(46) --258 + j*(123) --195 + j*(-302) -294 + j*(-168) -83 + j*(-46) --121 + j*(-111) --297 + j*(-122) --269 + j*(32) --171 + j*(-107) --89 + j*(336) --180 + j*(-263) --163 + j*(-48) -265 + j*(-103) -33 + j*(22) -448 + j*(99) --49 + j*(85) -259 + j*(-72) -13 + j*(7) --156 + j*(11) --112 + j*(186) -91 + j*(-44) -127 + j*(110) -190 + j*(-151) -26 + j*(-373) -115 + j*(177) -99 + j*(-327) -60 + j*(-87) --42 + j*(-71) -80 + j*(132) -173 + j*(276) -6 + j*(177) -46 + j*(-154) -6 + j*(115) -132 + j*(156) --303 + j*(257) -105 + j*(-506) -293 + j*(82) -23 + j*(62) --563 + j*(397) -308 + j*(17) --16 + j*(-53) --22 + j*(-210) -256 + j*(190) --40 + j*(308) -181 + j*(37) --179 + j*(-71) --42 + j*(37) --258 + j*(375) --81 + j*(115) --59 + j*(287) --66 + j*(122) --1 + j*(-218) -258 + j*(-6) -78 + j*(-95) -97 + j*(-148) --255 + j*(165) -226 + j*(0) -39 + j*(-141) -175 + j*(111) -21 + j*(110) --93 + j*(288) --240 + j*(-11) --163 + j*(77) -25 + j*(110) -70 + j*(78) -51 + j*(425) --74 + j*(-186) -121 + j*(-54) -270 + j*(64) -115 + j*(-173) --143 + j*(281) -88 + j*(-247) --20 + j*(-112) -156 + j*(-362) -33 + j*(-128) -97 + j*(-328) -28 + j*(-41) -58 + j*(47) -45 + j*(13) -206 + j*(560) -94 + j*(-16) -81 + j*(41) -270 + j*(13) -68 + j*(95) --33 + j*(-120) --173 + j*(-166) --64 + j*(124) -17 + j*(-88) -99 + j*(13) --380 + j*(6) --65 + j*(219) --16 + j*(-51) -35 + j*(146) -138 + j*(74) -453 + j*(-59) -337 + j*(-5) --218 + j*(-105) --360 + j*(-43) -99 + j*(-1) --12 + j*(-76) --183 + j*(221) -52 + j*(13) -86 + j*(-76) --265 + j*(-12) -61 + j*(-264) --29 + j*(91) -20 + j*(-177) -89 + j*(-281) -276 + j*(-13) -243 + j*(-251) --140 + j*(-55) -173 + j*(23) --14 + j*(-109) -59 + j*(57) -238 + j*(-78) -50 + j*(124) -132 + j*(70) --358 + j*(21) --228 + j*(51) --16 + j*(-243) --40 + j*(267) -49 + j*(231) -309 + j*(8) -32 + j*(-109) --147 + j*(190) -232 + j*(-166) --190 + j*(-117) -18 + j*(-43) --54 + j*(129) -145 + j*(110) --202 + j*(-232) --16 + j*(64) --320 + j*(354) -69 + j*(-96) --233 + j*(165) --93 + j*(-98) --182 + j*(-310) -144 + j*(-146) -192 + j*(6) -112 + j*(146) -214 + j*(352) --153 + j*(44) --218 + j*(-5) --76 + j*(110) -18 + j*(-194) --23 + j*(-85) --4 + j*(-256) -8 + j*(1) -49 + j*(111) --108 + j*(-100) --47 + j*(214) --72 + j*(143) --351 + j*(212) --51 + j*(62) --96 + j*(173) --56 + j*(-223) -101 + j*(-143) -245 + j*(-344) --74 + j*(103) -381 + j*(-153) -76 + j*(271) --126 + j*(-9) -62 + j*(90) -72 + j*(459) --132 + j*(-227) --57 + j*(161) --294 + j*(48) --158 + j*(65) --154 + j*(-49) -21 + j*(156) --289 + j*(226) -45 + j*(79) --156 + j*(61) -50 + j*(15) --368 + j*(-200) --202 + j*(64) -344 + j*(190) -31 + j*(139) -101 + j*(95) --446 + j*(74) -254 + j*(-9) -175 + j*(28) --158 + j*(115) --173 + j*(-316) --88 + j*(-179) --18 + j*(-386) -112 + j*(144) --368 + j*(250) --233 + j*(-171) --165 + j*(16) --188 + j*(71) --41 + j*(-57) -422 + j*(47) -62 + j*(-120) -18 + j*(4) --103 + j*(-131) --21 + j*(-190) --205 + j*(-158) -268 + j*(151) --250 + j*(156) --142 + j*(-12) -99 + j*(237) -363 + j*(78) -108 + j*(-13) -291 + j*(-148) --243 + j*(486) -177 + j*(33) -117 + j*(15) --126 + j*(-1) --185 + j*(-149) -115 + j*(108) -1 + j*(-47) -58 + j*(-262) -275 + j*(-234) --83 + j*(155) -291 + j*(72) --187 + j*(147) -57 + j*(14) -25 + j*(280) -318 + j*(23) --229 + j*(223) -164 + j*(86) -293 + j*(100) --52 + j*(-40) -87 + j*(118) --8 + j*(4) -134 + j*(47) -250 + j*(376) --73 + j*(64) -104 + j*(-39) --305 + j*(-147) --419 + j*(-16) --41 + j*(8) --83 + j*(-453) --19 + j*(201) --124 + j*(-91) --175 + j*(-139) -25 + j*(144) --28 + j*(303) --339 + j*(57) --139 + j*(319) --141 + j*(11) --109 + j*(-14) --6 + j*(-254) --8 + j*(80) -319 + j*(101) -94 + j*(-40) --202 + j*(-161) --329 + j*(-263) --115 + j*(-208) -250 + j*(-221) -214 + j*(29) -297 + j*(-151) -21 + j*(-16) -3 + j*(204) -8 + j*(-18) -302 + j*(-215) --216 + j*(-25) --54 + j*(-63) --113 + j*(-21) --218 + j*(-19) -102 + j*(-134) -303 + j*(-272) --199 + j*(-87) --115 + j*(-137) --52 + j*(16) --153 + j*(-173) -228 + j*(428) --43 + j*(-187) -149 + j*(-149) --83 + j*(373) --158 + j*(512) --306 + j*(64) --59 + j*(54) --94 + j*(-110) -240 + j*(-116) -99 + j*(52) -262 + j*(-194) --152 + j*(85) --105 + j*(218) --30 + j*(-55) -187 + j*(98) -308 + j*(-119) -54 + j*(-221) -103 + j*(175) -16 + j*(129) -149 + j*(-23) -95 + j*(7) --267 + j*(-37) -2 + j*(283) --237 + j*(30) --28 + j*(-204) -18 + j*(10) --25 + j*(-262) --252 + j*(45) --7 + j*(64) -139 + j*(325) --44 + j*(-243) --94 + j*(194) -132 + j*(192) -74 + j*(-332) -212 + j*(-189) --20 + j*(83) -56 + j*(-45) --371 + j*(-122) -10 + j*(134) --163 + j*(69) --305 + j*(35) -27 + j*(-186) -106 + j*(54) -226 + j*(8) --185 + j*(50) --3 + j*(-26) -11 + j*(136) --360 + j*(-132) -192 + j*(-67) -189 + j*(-46) --23 + j*(122) --119 + j*(-45) -187 + j*(-186) -24 + j*(78) -21 + j*(-125) -433 + j*(-60) -180 + j*(-35) --166 + j*(3) -44 + j*(134) -79 + j*(26) --82 + j*(103) --180 + j*(-40) -11 + j*(49) -147 + j*(132) -10 + j*(-36) -53 + j*(-157) -170 + j*(163) -71 + j*(213) -82 + j*(-135) --56 + j*(-138) -41 + j*(-115) --190 + j*(-4) -55 + j*(199) --144 + j*(-113) --397 + j*(-207) --165 + j*(-22) -46 + j*(122) --151 + j*(-102) -124 + j*(-79) -1 + j*(-262) -313 + j*(-66) -117 + j*(54) -110 + j*(-117) --254 + j*(-152) --2 + j*(-24) --199 + j*(25) --178 + j*(-133) --164 + j*(88) --18 + j*(-30) --166 + j*(83) -18 + j*(-286) -230 + j*(100) -153 + j*(-115) -49 + j*(-59) --39 + j*(-12) --412 + j*(-168) --151 + j*(293) -81 + j*(-356) -106 + j*(11) -101 + j*(-76) --103 + j*(489) -60 + j*(327) --254 + j*(-398) --96 + j*(-74) -115 + j*(-133) --114 + j*(91) -105 + j*(23) --334 + j*(-8) -421 + j*(-191) --281 + j*(-4) -49 + j*(-26) -83 + j*(-13) -102 + j*(202) -115 + j*(214) --18 + j*(322) -201 + j*(161) -34 + j*(-37) --204 + j*(181) -412 + j*(-41) -187 + j*(-15) --11 + j*(95) --8 + j*(-322) --364 + j*(40) --148 + j*(-52) -351 + j*(-114) -244 + j*(175) --123 + j*(-182) --59 + j*(-103) --60 + j*(98) --166 + j*(83) --192 + j*(71) --187 + j*(223) --24 + j*(-272) -209 + j*(-320) --45 + j*(-89) -438 + j*(-54) --64 + j*(-235) --346 + j*(-112) --12 + j*(142) --331 + j*(-138) -78 + j*(-123) --274 + j*(28) --6 + j*(-132) --64 + j*(258) -159 + j*(-135) -146 + j*(-85) --69 + j*(-122) -12 + j*(394) --24 + j*(-233) -194 + j*(144) -105 + j*(-107) -47 + j*(33) -30 + j*(-122) --27 + j*(-21) --48 + j*(-248) -354 + j*(91) --3 + j*(54) --440 + j*(-37) --127 + j*(198) -99 + j*(-142) -252 + j*(139) --150 + j*(-184) --355 + j*(-5) -192 + j*(243) --107 + j*(259) --95 + j*(81) --345 + j*(40) --207 + j*(-141) -47 + j*(76) --118 + j*(66) --161 + j*(128) --1 + j*(186) --45 + j*(-187) -106 + j*(224) --48 + j*(-237) -35 + j*(-229) --55 + j*(-293) --54 + j*(-86) --183 + j*(79) --15 + j*(-41) --122 + j*(231) -69 + j*(-17) -100 + j*(279) -320 + j*(76) --68 + j*(-83) -107 + j*(-70) --94 + j*(158) --93 + j*(122) --141 + j*(22) -65 + j*(91) --390 + j*(-91) --216 + j*(35) -37 + j*(-191) --57 + j*(14) -57 + j*(-288) -378 + j*(344) -42 + j*(448) -38 + j*(66) --76 + j*(-260) -298 + j*(-250) -13 + j*(-370) -156 + j*(-169) -72 + j*(-215) -173 + j*(289) -194 + j*(130) --23 + j*(202) --22 + j*(298) -148 + j*(-113) --131 + j*(-168) -339 + j*(107) -172 + j*(245) --136 + j*(-105) --186 + j*(-156) --67 + j*(221) --139 + j*(-42) -151 + j*(247) --13 + j*(24) -41 + j*(139) --165 + j*(185) --55 + j*(-143) -35 + j*(-252) --148 + j*(349) --147 + j*(-26) -36 + j*(-332) --58 + j*(-306) --152 + j*(107) -157 + j*(-163) --195 + j*(68) -241 + j*(282) -18 + j*(-115) -211 + j*(-32) -185 + j*(309) --76 + j*(122) -114 + j*(6) --58 + j*(-52) --161 + j*(-116) -6 + j*(159) -141 + j*(173) --134 + j*(-146) --243 + j*(250) -38 + j*(221) --122 + j*(-24) --37 + j*(454) --119 + j*(-127) -122 + j*(-71) -52 + j*(-101) -63 + j*(-133) -8 + j*(-279) -214 + j*(-154) --467 + j*(110) -78 + j*(6) --216 + j*(-87) --147 + j*(-160) --38 + j*(161) -124 + j*(245) --56 + j*(-250) --70 + j*(-132) --235 + j*(117) --25 + j*(36) -67 + j*(-18) -115 + j*(-83) -88 + j*(278) --175 + j*(-8) -285 + j*(-65) -29 + j*(-49) --42 + j*(-153) --23 + j*(-26) -153 + j*(-66) --218 + j*(251) --37 + j*(228) --21 + j*(30) -101 + j*(-76) --5 + j*(-206) -49 + j*(37) --100 + j*(-129) -3 + j*(-216) -9 + j*(49) -247 + j*(13) --20 + j*(99) --19 + j*(134) --2 + j*(144) -153 + j*(112) -362 + j*(91) --74 + j*(-28) -211 + j*(-182) -105 + j*(226) --100 + j*(130) -37 + j*(16) -130 + j*(167) --88 + j*(-218) -143 + j*(84) -31 + j*(35) -212 + j*(390) -1 + j*(-293) --12 + j*(-161) --49 + j*(-143) --91 + j*(-130) -6 + j*(-74) --59 + j*(185) --177 + j*(92) --19 + j*(25) --232 + j*(-138) -110 + j*(103) --40 + j*(131) -3 + j*(-152) --55 + j*(105) -260 + j*(-247) -286 + j*(-23) -98 + j*(-16) -54 + j*(33) --358 + j*(-16) --146 + j*(107) --249 + j*(-199) --158 + j*(87) --72 + j*(-110) -133 + j*(-196) --141 + j*(354) -71 + j*(-152) -159 + j*(192) --162 + j*(62) -182 + j*(344) --2 + j*(14) --293 + j*(321) --41 + j*(-82) --24 + j*(225) --17 + j*(-158) --37 + j*(103) -42 + j*(-50) --33 + j*(229) --22 + j*(54) --105 + j*(-125) -343 + j*(298) --211 + j*(231) -75 + j*(-85) -181 + j*(-33) -194 + j*(205) --36 + j*(103) --325 + j*(-103) --148 + j*(-293) --143 + j*(-52) --294 + j*(16) --147 + j*(-192) --132 + j*(64) --75 + j*(-105) --279 + j*(-113) -15 + j*(-10) -103 + j*(-361) -45 + j*(315) --8 + j*(-119) --352 + j*(-97) --8 + j*(-74) --363 + j*(112) --196 + j*(67) -226 + j*(-40) -235 + j*(117) --140 + j*(47) -33 + j*(161) -149 + j*(162) --468 + j*(-17) --270 + j*(-72) --335 + j*(-178) --23 + j*(184) -156 + j*(361) -184 + j*(177) -151 + j*(141) --100 + j*(-231) --2 + j*(71) --3 + j*(103) -230 + j*(105) -50 + j*(306) --194 + j*(216) -101 + j*(-252) --187 + j*(88) --114 + j*(43) -6 + j*(124) --143 + j*(-50) --237 + j*(33) -115 + j*(144) --112 + j*(-465) -86 + j*(-54) --125 + j*(-146) -127 + j*(-179) -175 + j*(-162) -146 + j*(-141) --272 + j*(-158) -107 + j*(168) -48 + j*(143) --42 + j*(-18) -33 + j*(83) --213 + j*(269) -58 + j*(-211) --140 + j*(100) -29 + j*(-171) -311 + j*(-104) --13 + j*(127) --55 + j*(110) --191 + j*(4) --16 + j*(93) --338 + j*(255) -103 + j*(55) --88 + j*(-111) -41 + j*(49) -191 + j*(124) -145 + j*(163) -18 + j*(-132) --46 + j*(81) --59 + j*(-154) -277 + j*(179) -199 + j*(104) -40 + j*(4) --46 + j*(28) --13 + j*(-26) -89 + j*(11) --56 + j*(91) --228 + j*(-152) --7 + j*(64) -122 + j*(-274) -151 + j*(-303) --273 + j*(-251) --60 + j*(264) -49 + j*(-74) --56 + j*(-255) -445 + j*(210) -33 + j*(-155) --271 + j*(-182) --36 + j*(-136) -8 + j*(-16) --204 + j*(-123) --124 + j*(33) --139 + j*(32) -90 + j*(-192) -282 + j*(83) -48 + j*(-245) -129 + j*(98) --54 + j*(344) --18 + j*(252) --279 + j*(-146) --115 + j*(-52) -79 + j*(192) -132 + j*(22) --103 + j*(-162) --42 + j*(64) -9 + j*(-185) --132 + j*(-54) -9 + j*(129) -211 + j*(50) --164 + j*(-13) -258 + j*(-100) -194 + j*(145) --420 + j*(-276) -27 + j*(-30) --106 + j*(74) --71 + j*(378) --296 + j*(178) -190 + j*(175) -217 + j*(-64) -455 + j*(-68) -69 + j*(144) -216 + j*(6) -25 + j*(39) -39 + j*(78) --31 + j*(134) -165 + j*(-6) --160 + j*(-95) -185 + j*(-281) -71 + j*(402) --155 + j*(414) -159 + j*(-88) -302 + j*(-307) -73 + j*(-36) --81 + j*(215) -142 + j*(-110) -103 + j*(-156) -195 + j*(-28) -185 + j*(167) --89 + j*(117) --147 + j*(-75) -118 + j*(-332) --7 + j*(104) -211 + j*(-114) -201 + j*(-291) -49 + j*(88) -159 + j*(-75) --327 + j*(-508) -26 + j*(13) --387 + j*(-252) -148 + j*(-234) -23 + j*(-49) -78 + j*(-138) -189 + j*(-103) --20 + j*(117) --33 + j*(6) -149 + j*(-153) --85 + j*(-231) --127 + j*(135) --136 + j*(-206) --73 + j*(69) --134 + j*(7) --264 + j*(-69) --82 + j*(89) --248 + j*(127) -30 + j*(-12) --138 + j*(-164) -123 + j*(-185) -237 + j*(-33) --187 + j*(-103) --115 + j*(-215) -28 + j*(347) -220 + j*(131) -281 + j*(-134) --107 + j*(110) -133 + j*(-53) -204 + j*(132) --85 + j*(289) -235 + j*(-135) --145 + j*(153) --87 + j*(332) --213 + j*(-73) --153 + j*(-220) --214 + j*(-223) -59 + j*(-12) -48 + j*(-79) -11 + j*(8) --46 + j*(-181) -94 + j*(141) -39 + j*(-21) -70 + j*(-293) -145 + j*(13) -32 + j*(-18) -134 + j*(129) --110 + j*(-243) --127 + j*(292) -4 + j*(209) --139 + j*(-44) --21 + j*(-40) -35 + j*(-84) --316 + j*(-268) --195 + j*(166) --95 + j*(-24) -233 + j*(-18) -240 + j*(-88) --66 + j*(-143) -155 + j*(9) -266 + j*(235) --94 + j*(-28) -117 + j*(35) --189 + j*(9) --205 + j*(40) --74 + j*(252) --141 + j*(150) --29 + j*(-57) -49 + j*(103) --57 + j*(251) -109 + j*(95) -284 + j*(-16) -11 + j*(-96) --289 + j*(-351) --6 + j*(-222) -355 + j*(118) --139 + j*(179) --143 + j*(137) -88 + j*(-86) -243 + j*(-131) -117 + j*(-6) --489 + j*(70) -74 + j*(245) -93 + j*(88) --62 + j*(54) -218 + j*(176) --146 + j*(-126) -28 + j*(-53) -86 + j*(13) -203 + j*(153) -150 + j*(74) -200 + j*(320) -95 + j*(142) -58 + j*(156) -345 + j*(-52) --59 + j*(462) --22 + j*(-43) --160 + j*(141) -313 + j*(-104) --190 + j*(-67) -25 + j*(-103) --305 + j*(17) -53 + j*(-52) --36 + j*(-101) --67 + j*(-47) --198 + j*(202) -231 + j*(-218) --62 + j*(146) -68 + j*(-172) --148 + j*(-134) --32 + j*(-184) --378 + j*(88) --248 + j*(12) --37 + j*(-68) -11 + j*(44) --19 + j*(-67) -215 + j*(262) --190 + j*(229) --277 + j*(62) -140 + j*(-204) --219 + j*(-9) -78 + j*(-64) -249 + j*(16) --1 + j*(-115) -58 + j*(276) --94 + j*(-193) -80 + j*(-61) -333 + j*(77) -150 + j*(233) --251 + j*(-255) -0 + j*(340) --205 + j*(-45) -80 + j*(-305) -112 + j*(-45) --28 + j*(-1) --1 + j*(22) -125 + j*(-304) --276 + j*(-24) --28 + j*(-177) -117 + j*(197) -192 + j*(-29) -40 + j*(158) --304 + j*(-122) --84 + j*(-35) -160 + j*(-28) -36 + j*(110) -119 + j*(7) --35 + j*(-127) -8 + j*(33) -161 + j*(48) --65 + j*(158) --237 + j*(-220) --65 + j*(-294) -157 + j*(155) --8 + j*(-296) -18 + j*(-273) -173 + j*(-16) -136 + j*(23) -85 + j*(156) -1 + j*(144) -147 + j*(-281) --95 + j*(94) --69 + j*(-103) -165 + j*(-25) --196 + j*(257) -80 + j*(195) -31 + j*(-11) --267 + j*(-69) --208 + j*(-127) --180 + j*(-87) --90 + j*(48) -69 + j*(-47) --163 + j*(-314) --4 + j*(-166) --45 + j*(460) --5 + j*(-4) -105 + j*(-238) --240 + j*(158) --145 + j*(72) -95 + j*(-35) --4 + j*(-213) -14 + j*(182) --33 + j*(123) --385 + j*(170) -32 + j*(-27) --19 + j*(-164) --245 + j*(68) --16 + j*(-67) -226 + j*(88) --130 + j*(-112) -4 + j*(-4) --320 + j*(54) --154 + j*(-131) -184 + j*(33) -137 + j*(-269) -148 + j*(-68) --93 + j*(-13) -94 + j*(-280) -35 + j*(98) --104 + j*(-165) --71 + j*(-84) -293 + j*(-71) -247 + j*(159) --91 + j*(-63) --95 + j*(246) --124 + j*(49) --158 + j*(227) --146 + j*(-84) --185 + j*(-206) -101 + j*(129) --45 + j*(-361) --140 + j*(115) -8 + j*(-83) --426 + j*(-45) -365 + j*(-120) --115 + j*(98) --247 + j*(192) -23 + j*(39) --22 + j*(205) -30 + j*(40) -196 + j*(-71) --74 + j*(193) -76 + j*(-51) --123 + j*(-93) --37 + j*(-251) --26 + j*(170) --263 + j*(43) --42 + j*(-224) -214 + j*(153) --33 + j*(86) --137 + j*(158) -148 + j*(122) -68 + j*(26) -341 + j*(-75) -121 + j*(96) -74 + j*(-235) -25 + j*(-41) -50 + j*(141) --183 + j*(69) -74 + j*(-94) -119 + j*(-129) -55 + j*(5) --132 + j*(267) --167 + j*(-24) --273 + j*(139) -270 + j*(59) --114 + j*(-62) -46 + j*(63) --74 + j*(42) -378 + j*(-223) -27 + j*(122) -121 + j*(372) -278 + j*(116) --33 + j*(-276) -9 + j*(-49) --403 + j*(138) --5 + j*(342) --109 + j*(-95) --31 + j*(-43) -62 + j*(-186) -163 + j*(-233) --28 + j*(144) -194 + j*(93) -69 + j*(-206) -180 + j*(-120) --72 + j*(-62) --52 + j*(-166) -81 + j*(128) -239 + j*(-315) -30 + j*(-97) -194 + j*(-300) -26 + j*(197) -12 + j*(-54) --13 + j*(146) -322 + j*(55) --341 + j*(-282) -29 + j*(-225) --91 + j*(7) --160 + j*(64) -7 + j*(-127) -28 + j*(-158) --97 + j*(283) --276 + j*(62) --53 + j*(-362) -59 + j*(18) -227 + j*(-390) --86 + j*(132) --105 + j*(-513) --87 + j*(29) -35 + j*(-110) -18 + j*(47) -180 + j*(-45) --112 + j*(5) -44 + j*(-31) --144 + j*(66) --284 + j*(187) --373 + j*(183) -66 + j*(-160) -378 + j*(209) --360 + j*(-33) --181 + j*(-174) -31 + j*(-209) -66 + j*(-187) --224 + j*(-27) --118 + j*(-124) -16 + j*(156) --29 + j*(163) --112 + j*(69) --10 + j*(191) -114 + j*(-103) -8 + j*(16) --132 + j*(105) --221 + j*(211) --187 + j*(-11) -100 + j*(-49) --27 + j*(52) --62 + j*(1) -48 + j*(-86) --243 + j*(296) --307 + j*(-22) -47 + j*(-23) --126 + j*(-111) --93 + j*(-12) --46 + j*(-265) -71 + j*(-1) --52 + j*(42) --180 + j*(344) -78 + j*(-95) --167 + j*(-28) --293 + j*(196) -247 + j*(63) -112 + j*(383) -225 + j*(-232) -97 + j*(-60) --57 + j*(-233) --180 + j*(-136) -130 + j*(-187) --62 + j*(-65) -13 + j*(14) --9 + j*(267) --243 + j*(-458) -21 + j*(267) --57 + j*(-45) --148 + j*(130) -86 + j*(251) --366 + j*(93) --375 + j*(302) -107 + j*(-11) --12 + j*(-207) -198 + j*(-397) --346 + j*(15) --19 + j*(177) -28 + j*(-23) --87 + j*(-81) --164 + j*(-117) --184 + j*(42) --43 + j*(231) --49 + j*(-143) --209 + j*(-252) --344 + j*(171) -261 + j*(200) -210 + j*(2) --78 + j*(18) -120 + j*(-31) --46 + j*(37) -105 + j*(228) -252 + j*(-62) -76 + j*(190) --200 + j*(-88) -112 + j*(31) -97 + j*(46) --14 + j*(191) -122 + j*(70) --110 + j*(132) -52 + j*(-151) --161 + j*(69) -74 + j*(228) --170 + j*(41) --59 + j*(-354) --98 + j*(325) -64 + j*(-64) --235 + j*(175) --230 + j*(-93) -83 + j*(-48) --274 + j*(-86) -133 + j*(-92) --118 + j*(190) --192 + j*(232) -107 + j*(226) --178 + j*(-91) --45 + j*(35) -212 + j*(194) -38 + j*(-66) -2 + j*(142) -156 + j*(296) --62 + j*(38) -34 + j*(-358) --133 + j*(-114) -94 + j*(80) --299 + j*(41) -23 + j*(264) --223 + j*(515) --82 + j*(-98) --180 + j*(175) --160 + j*(-163) --42 + j*(81) --110 + j*(-93) --95 + j*(-186) --182 + j*(-190) -29 + j*(-227) -36 + j*(107) --25 + j*(-239) --147 + j*(-128) -214 + j*(178) --144 + j*(-26) --162 + j*(210) --1 + j*(-170) --182 + j*(76) --214 + j*(272) -209 + j*(112) --335 + j*(199) -202 + j*(93) -192 + j*(-119) --160 + j*(65) -231 + j*(-61) --37 + j*(-151) -77 + j*(114) -293 + j*(34) --203 + j*(-176) --164 + j*(142) --233 + j*(269) --45 + j*(227) -313 + j*(74) --52 + j*(210) --396 + j*(-31) --111 + j*(-95) --11 + j*(83) -112 + j*(246) --59 + j*(95) -196 + j*(121) --364 + j*(-285) -139 + j*(284) --301 + j*(-78) --274 + j*(-334) --413 + j*(-324) -25 + j*(-57) --251 + j*(-60) -552 + j*(-140) -98 + j*(559) -452 + j*(-165) -334 + j*(-16) --477 + j*(-221) --273 + j*(82) --170 + j*(127) -600 + j*(348) -412 + j*(187) -392 + j*(393) -356 + j*(-431) --303 + j*(-270) --383 + j*(388) -107 + j*(-441) --371 + j*(155) -385 + j*(398) --262 + j*(-58) -244 + j*(-265) -494 + j*(359) --245 + j*(214) -141 + j*(-274) -281 + j*(-645) -252 + j*(222) --252 + j*(-163) --350 + j*(371) -143 + j*(-293) --426 + j*(-419) -107 + j*(-83) --183 + j*(-363) -431 + j*(-91) --557 + j*(-171) --7 + j*(576) -393 + j*(-195) --415 + j*(387) -95 + j*(-383) -56 + j*(156) -223 + j*(433) --670 + j*(232) --78 + j*(192) -327 + j*(187) --47 + j*(-198) --47 + j*(379) -158 + j*(-204) -170 + j*(40) -120 + j*(-402) --57 + j*(-609) -363 + j*(197) -572 + j*(240) -159 + j*(277) -51 + j*(594) -284 + j*(-165) --221 + j*(406) --83 + j*(-173) -248 + j*(-268) --106 + j*(67) --233 + j*(330) --208 + j*(-184) -414 + j*(-62) --170 + j*(609) --309 + j*(177) -278 + j*(-119) -611 + j*(251) --67 + j*(438) -354 + j*(87) -344 + j*(225) -388 + j*(190) -386 + j*(273) --235 + j*(-399) -450 + j*(89) --129 + j*(-380) -307 + j*(-317) -6 + j*(454) --21 + j*(683) -382 + j*(607) -26 + j*(269) -397 + j*(394) -525 + j*(-202) --373 + j*(-337) -607 + j*(363) -142 + j*(235) -320 + j*(-230) -276 + j*(223) --82 + j*(-39) --41 + j*(374) -298 + j*(313) --453 + j*(136) --487 + j*(-484) --50 + j*(214) --265 + j*(259) --185 + j*(-32) --268 + j*(6) -335 + j*(414) --385 + j*(-177) --438 + j*(-168) --153 + j*(475) --93 + j*(223) --279 + j*(283) -481 + j*(-119) -2 + j*(-363) -571 + j*(346) -342 + j*(143) --379 + j*(175) --30 + j*(-334) --431 + j*(237) -113 + j*(-408) -420 + j*(-398) --101 + j*(-35) --363 + j*(77) --421 + j*(129) -378 + j*(166) --316 + j*(-40) -402 + j*(-251) -22 + j*(-351) -223 + j*(-376) -273 + j*(599) --213 + j*(30) -269 + j*(-317) -209 + j*(357) --156 + j*(517) -97 + j*(504) -296 + j*(-239) -65 + j*(1) -278 + j*(342) --175 + j*(-567) -325 + j*(-247) --455 + j*(-64) -512 + j*(-163) -148 + j*(542) -183 + j*(273) --224 + j*(53) -327 + j*(256) -124 + j*(-139) -63 + j*(124) --57 + j*(-381) -112 + j*(-13) -269 + j*(-236) --104 + j*(-487) --227 + j*(-422) -434 + j*(-423) -387 + j*(-274) --118 + j*(110) -197 + j*(342) --96 + j*(300) -413 + j*(-33) --184 + j*(-374) -451 + j*(68) -435 + j*(-132) --244 + j*(-332) -482 + j*(296) -500 + j*(-520) -41 + j*(-66) --137 + j*(678) --433 + j*(361) --573 + j*(576) --350 + j*(255) --185 + j*(-711) -491 + j*(403) --203 + j*(-359) -36 + j*(-153) --199 + j*(-299) -312 + j*(-607) -17 + j*(82) --284 + j*(311) --651 + j*(349) --317 + j*(-525) -461 + j*(-175) --272 + j*(-30) --433 + j*(392) --204 + j*(242) --132 + j*(330) -37 + j*(-193) -461 + j*(-472) --188 + j*(-404) -136 + j*(434) -489 + j*(-688) --261 + j*(-331) --79 + j*(323) --181 + j*(-231) -236 + j*(483) -294 + j*(-152) -118 + j*(-52) -286 + j*(299) -353 + j*(-41) --250 + j*(262) --332 + j*(385) --1 + j*(-199) -547 + j*(-29) -135 + j*(307) -150 + j*(348) --211 + j*(386) --124 + j*(-317) -197 + j*(289) -6 + j*(224) --571 + j*(327) --127 + j*(-331) -164 + j*(-490) --211 + j*(428) -507 + j*(99) -1 + j*(-32) --378 + j*(-261) -396 + j*(-520) --180 + j*(332) -318 + j*(119) --143 + j*(364) --177 + j*(527) --141 + j*(47) -180 + j*(104) --38 + j*(-321) -185 + j*(353) --414 + j*(250) -29 + j*(-441) --202 + j*(247) -16 + j*(62) -432 + j*(467) --206 + j*(175) -94 + j*(-132) -321 + j*(369) -705 + j*(170) -346 + j*(512) --368 + j*(-420) -53 + j*(117) -98 + j*(-211) --267 + j*(251) -366 + j*(144) -630 + j*(144) --187 + j*(333) --271 + j*(566) --344 + j*(-87) -437 + j*(316) --181 + j*(423) --280 + j*(90) -497 + j*(226) --191 + j*(-57) -334 + j*(122) --228 + j*(309) -412 + j*(-351) -289 + j*(193) -194 + j*(124) -293 + j*(-198) --175 + j*(343) --222 + j*(-327) -40 + j*(-205) -357 + j*(-335) --131 + j*(-187) -5 + j*(-491) -38 + j*(330) -6 + j*(274) -207 + j*(113) --339 + j*(-238) -245 + j*(-246) --46 + j*(-59) --375 + j*(-393) --231 + j*(515) -53 + j*(262) --224 + j*(190) --363 + j*(-43) -224 + j*(150) -122 + j*(-337) --296 + j*(-264) -73 + j*(445) --217 + j*(359) --270 + j*(-305) --342 + j*(526) -286 + j*(-655) --216 + j*(410) -606 + j*(368) -540 + j*(347) --66 + j*(-136) -149 + j*(342) -64 + j*(-315) --483 + j*(-236) --313 + j*(-325) --150 + j*(238) --175 + j*(-165) --239 + j*(409) -166 + j*(-18) -282 + j*(-151) --202 + j*(-446) -452 + j*(360) --205 + j*(-263) --283 + j*(320) --358 + j*(266) -170 + j*(28) --288 + j*(-393) -97 + j*(423) -122 + j*(425) --6 + j*(146) -144 + j*(-282) -368 + j*(413) --320 + j*(410) --513 + j*(-503) -237 + j*(-528) --398 + j*(254) --237 + j*(474) --128 + j*(499) -233 + j*(396) -262 + j*(404) -240 + j*(-390) --372 + j*(245) --313 + j*(-37) --99 + j*(-187) --301 + j*(-677) --321 + j*(120) -294 + j*(-131) -276 + j*(-228) --313 + j*(-604) --140 + j*(-262) --437 + j*(-173) -98 + j*(192) -235 + j*(394) -256 + j*(-503) -336 + j*(383) -138 + j*(277) --56 + j*(260) --305 + j*(-528) -206 + j*(59) -221 + j*(191) -552 + j*(-141) -15 + j*(434) -223 + j*(24) -56 + j*(325) --49 + j*(238) --410 + j*(270) -11 + j*(-322) --91 + j*(-492) --315 + j*(-44) --165 + j*(-332) -242 + j*(108) -29 + j*(226) -95 + j*(-47) --218 + j*(-109) -251 + j*(-426) --332 + j*(213) -33 + j*(443) -207 + j*(-475) -148 + j*(-1) --147 + j*(-504) --158 + j*(1) -378 + j*(15) --612 + j*(-174) -255 + j*(182) -240 + j*(-387) --206 + j*(176) -523 + j*(-181) -241 + j*(-255) --362 + j*(-265) -84 + j*(100) --299 + j*(165) -291 + j*(192) --109 + j*(-377) --72 + j*(532) --86 + j*(-276) -250 + j*(489) --301 + j*(-421) -187 + j*(401) --241 + j*(58) --369 + j*(-199) -23 + j*(501) --194 + j*(-318) --278 + j*(578) -552 + j*(223) --197 + j*(-253) -231 + j*(-304) --33 + j*(-308) -296 + j*(437) --462 + j*(445) -57 + j*(-146) --127 + j*(94) -98 + j*(21) -392 + j*(-337) --290 + j*(244) --216 + j*(434) -112 + j*(-111) -1 + j*(-450) -294 + j*(115) --486 + j*(-211) --293 + j*(-436) --181 + j*(315) -231 + j*(375) -192 + j*(-240) -200 + j*(-343) --310 + j*(34) --459 + j*(-279) --173 + j*(-120) -391 + j*(-253) --197 + j*(-226) -224 + j*(-334) --604 + j*(325) --18 + j*(-379) -269 + j*(-285) -454 + j*(483) --172 + j*(-185) --479 + j*(135) -319 + j*(275) -423 + j*(-495) --319 + j*(315) -22 + j*(466) --86 + j*(-120) -224 + j*(198) -210 + j*(-262) -106 + j*(170) --293 + j*(220) -491 + j*(524) -128 + j*(525) --318 + j*(419) -352 + j*(-143) --196 + j*(130) --222 + j*(317) -302 + j*(-421) -388 + j*(-199) --243 + j*(395) -87 + j*(397) --383 + j*(296) -99 + j*(-499) --97 + j*(-214) -279 + j*(-408) --428 + j*(-327) -250 + j*(-131) -260 + j*(110) --346 + j*(323) --204 + j*(341) --344 + j*(-276) -266 + j*(-33) --482 + j*(-466) --284 + j*(10) --331 + j*(236) -66 + j*(272) --415 + j*(227) -16 + j*(81) --647 + j*(671) --20 + j*(93) --130 + j*(-244) --272 + j*(74) --243 + j*(379) -168 + j*(-558) --49 + j*(264) --257 + j*(231) --298 + j*(231) -235 + j*(496) -263 + j*(77) --192 + j*(250) -110 + j*(87) --301 + j*(49) -391 + j*(-658) -482 + j*(-317) -267 + j*(-197) -89 + j*(-107) -240 + j*(-375) --354 + j*(-299) --441 + j*(-1) -113 + j*(-134) -530 + j*(-79) -405 + j*(-101) -476 + j*(45) -460 + j*(145) -332 + j*(-77) --86 + j*(-153) -74 + j*(-574) --298 + j*(-58) --220 + j*(-371) -438 + j*(192) --325 + j*(175) --132 + j*(-379) -225 + j*(96) -307 + j*(-55) --137 + j*(303) --112 + j*(423) --327 + j*(-241) --329 + j*(351) -62 + j*(-287) -372 + j*(-214) -426 + j*(-216) -176 + j*(-170) --449 + j*(-296) -522 + j*(-1) --66 + j*(396) --223 + j*(92) -228 + j*(165) --233 + j*(105) --272 + j*(-164) -248 + j*(121) --518 + j*(20) --65 + j*(-497) --272 + j*(118) -166 + j*(-117) --279 + j*(-284) -426 + j*(-590) --317 + j*(346) -197 + j*(421) -552 + j*(181) --163 + j*(290) -253 + j*(-554) -60 + j*(16) --336 + j*(-438) --154 + j*(-322) --202 + j*(188) --177 + j*(-8) --427 + j*(-361) --353 + j*(27) -406 + j*(119) --326 + j*(-155) -170 + j*(-190) --235 + j*(59) --67 + j*(287) -106 + j*(438) -192 + j*(-505) -173 + j*(-77) --147 + j*(-275) --683 + j*(342) --411 + j*(433) -307 + j*(4) --506 + j*(44) -322 + j*(-171) -337 + j*(-151) -276 + j*(332) --269 + j*(293) --8 + j*(151) --552 + j*(216) --168 + j*(-276) -195 + j*(-460) -287 + j*(645) --132 + j*(-112) -681 + j*(355) -336 + j*(-137) --539 + j*(-412) -82 + j*(433) --363 + j*(-254) --175 + j*(311) --180 + j*(155) -759 + j*(222) --756 + j*(387) -598 + j*(11) --66 + j*(47) -354 + j*(-71) --262 + j*(-247) --397 + j*(14) -400 + j*(-116) -141 + j*(132) -387 + j*(38) -269 + j*(-296) -457 + j*(54) --173 + j*(85) --370 + j*(191) -53 + j*(-285) --457 + j*(-389) -60 + j*(-470) -384 + j*(-293) --405 + j*(139) --138 + j*(168) --107 + j*(-69) -334 + j*(-50) -210 + j*(-148) -268 + j*(-327) --325 + j*(316) --157 + j*(3) --202 + j*(-96) --214 + j*(244) --336 + j*(-150) -495 + j*(-384) -380 + j*(283) --184 + j*(-419) -293 + j*(339) -178 + j*(67) --156 + j*(249) --563 + j*(407) --561 + j*(185) --93 + j*(-275) --299 + j*(363) -356 + j*(482) -301 + j*(163) --518 + j*(-438) --379 + j*(-109) --474 + j*(438) -486 + j*(180) -204 + j*(648) --122 + j*(190) --387 + j*(-214) -10 + j*(238) -124 + j*(406) -420 + j*(-313) --163 + j*(110) --330 + j*(-315) -303 + j*(262) -371 + j*(189) -452 + j*(-500) -430 + j*(-48) --10 + j*(129) --278 + j*(136) --366 + j*(420) -163 + j*(-250) -337 + j*(-217) -326 + j*(473) --353 + j*(-308) --11 + j*(-25) -106 + j*(-86) -237 + j*(325) -368 + j*(340) -53 + j*(-92) -116 + j*(-206) -163 + j*(206) --122 + j*(185) -282 + j*(-407) --41 + j*(35) --279 + j*(110) --204 + j*(4) -42 + j*(236) --190 + j*(66) -2 + j*(-25) --112 + j*(-47) -35 + j*(-76) -165 + j*(293) --218 + j*(-17) --69 + j*(-71) --158 + j*(48) -88 + j*(-57) --67 + j*(-9) --144 + j*(-40) --216 + j*(218) --161 + j*(88) -100 + j*(89) -226 + j*(219) --10 + j*(0) -96 + j*(-326) -79 + j*(-63) --82 + j*(219) -345 + j*(69) -486 + j*(-264) --37 + j*(11) -373 + j*(-105) --292 + j*(-99) -214 + j*(-145) --187 + j*(-156) --96 + j*(-194) --200 + j*(-57) --134 + j*(-142) -152 + j*(-251) --112 + j*(25) --33 + j*(179) --177 + j*(-7) --245 + j*(1) --114 + j*(122) --9 + j*(-83) --157 + j*(132) --173 + j*(-385) --25 + j*(308) -280 + j*(-180) --240 + j*(-129) --286 + j*(-115) --184 + j*(161) -180 + j*(-82) --2 + j*(383) --139 + j*(192) -112 + j*(-71) -178 + j*(-163) -104 + j*(15) --103 + j*(-185) --207 + j*(197) --78 + j*(108) -86 + j*(60) -52 + j*(296) --240 + j*(-98) --9 + j*(150) -107 + j*(-222) -281 + j*(223) --79 + j*(-42) -49 + j*(-105) --157 + j*(84) -42 + j*(-150) -80 + j*(-23) -178 + j*(-237) -269 + j*(119) --438 + j*(-72) --51 + j*(-114) --279 + j*(-76) -130 + j*(97) --125 + j*(138) -100 + j*(-168) --332 + j*(155) -112 + j*(413) -175 + j*(-136) --450 + j*(77) -34 + j*(51) --140 + j*(257) -170 + j*(-117) --275 + j*(-221) -30 + j*(361) -0 + j*(35) --165 + j*(-214) -227 + j*(186) -326 + j*(363) -175 + j*(11) --52 + j*(51) -153 + j*(-244) -0 + j*(-8) --78 + j*(68) -25 + j*(-67) -88 + j*(7) --204 + j*(216) -117 + j*(127) --214 + j*(-161) -192 + j*(285) --366 + j*(13) -185 + j*(92) --117 + j*(-243) -132 + j*(0) -141 + j*(9) --138 + j*(-232) --107 + j*(147) -175 + j*(-41) -35 + j*(47) -175 + j*(-52) -109 + j*(-82) --18 + j*(-75) -94 + j*(47) -76 + j*(111) -59 + j*(-148) -137 + j*(168) --24 + j*(171) --44 + j*(262) --299 + j*(-66) -130 + j*(-274) -64 + j*(-99) -10 + j*(-214) --251 + j*(330) --77 + j*(-100) --239 + j*(226) --83 + j*(-61) --240 + j*(162) --475 + j*(173) --32 + j*(-143) -112 + j*(238) --8 + j*(-178) --95 + j*(247) --33 + j*(87) --302 + j*(298) -202 + j*(69) -33 + j*(-87) --184 + j*(-31) -234 + j*(220) -122 + j*(-123) --64 + j*(155) -106 + j*(115) -161 + j*(56) -72 + j*(243) --27 + j*(47) --3 + j*(-138) --302 + j*(-216) -156 + j*(-93) --139 + j*(-104) --316 + j*(45) --161 + j*(345) --354 + j*(110) --79 + j*(155) -193 + j*(21) -31 + j*(-125) --119 + j*(-205) -35 + j*(21) --75 + j*(241) -23 + j*(-146) -224 + j*(-222) --171 + j*(231) --61 + j*(-42) --372 + j*(102) --19 + j*(-151) -368 + j*(89) -318 + j*(-52) --327 + j*(-301) -47 + j*(57) --243 + j*(-231) --461 + j*(59) -118 + j*(-65) -67 + j*(202) -402 + j*(-226) --123 + j*(-42) --127 + j*(325) --24 + j*(-166) -185 + j*(161) -111 + j*(-74) --44 + j*(-95) --290 + j*(137) --125 + j*(-220) -54 + j*(-77) -70 + j*(46) -153 + j*(-112) -17 + j*(170) --185 + j*(77) -193 + j*(140) --388 + j*(150) --381 + j*(-216) --11 + j*(262) --130 + j*(8) -149 + j*(-19) -240 + j*(134) -101 + j*(-161) -147 + j*(-86) -101 + j*(51) -110 + j*(-91) -67 + j*(126) -122 + j*(-72) --100 + j*(-166) -146 + j*(-159) --175 + j*(208) --90 + j*(-16) --288 + j*(-130) --256 + j*(-168) --29 + j*(62) -68 + j*(95) -18 + j*(95) -147 + j*(-91) --11 + j*(162) -136 + j*(35) -98 + j*(33) --180 + j*(308) -171 + j*(-5) --114 + j*(25) --30 + j*(-217) --88 + j*(184) -45 + j*(91) -214 + j*(-21) -91 + j*(348) --92 + j*(-296) --58 + j*(96) -38 + j*(-119) --202 + j*(135) --28 + j*(-60) --123 + j*(31) -102 + j*(12) --132 + j*(217) --28 + j*(245) --267 + j*(5) -41 + j*(249) --21 + j*(-147) -102 + j*(-320) --274 + j*(-25) -156 + j*(-100) -100 + j*(-124) --136 + j*(275) -320 + j*(-35) --115 + j*(104) --11 + j*(-205) --254 + j*(-291) --9 + j*(-318) --97 + j*(195) -279 + j*(29) -269 + j*(227) -67 + j*(-39) --136 + j*(241) --96 + j*(-19) -250 + j*(-127) -84 + j*(-129) -228 + j*(90) --98 + j*(23) --46 + j*(-4) -42 + j*(47) --15 + j*(-37) --122 + j*(-230) -67 + j*(163) -176 + j*(-43) -82 + j*(-132) -115 + j*(157) -86 + j*(33) --325 + j*(-20) --115 + j*(77) --33 + j*(-4) -197 + j*(161) -88 + j*(33) --55 + j*(72) -113 + j*(-60) -135 + j*(132) -9 + j*(291) --468 + j*(99) -122 + j*(-105) -95 + j*(-26) -29 + j*(-37) -40 + j*(-100) --100 + j*(26) --369 + j*(228) -86 + j*(-67) --47 + j*(-98) -52 + j*(-129) -271 + j*(-58) -131 + j*(-315) --78 + j*(361) --2 + j*(-98) -143 + j*(-180) -78 + j*(123) --77 + j*(-190) --92 + j*(-76) -151 + j*(71) --47 + j*(13) -246 + j*(-71) --178 + j*(59) -134 + j*(-88) -243 + j*(-98) --51 + j*(11) -244 + j*(45) --66 + j*(127) -44 + j*(223) -145 + j*(-98) --129 + j*(173) --226 + j*(330) -264 + j*(168) --93 + j*(27) --146 + j*(-133) --203 + j*(-310) -8 + j*(11) -378 + j*(112) -385 + j*(281) -182 + j*(-64) -35 + j*(158) --199 + j*(-1) --168 + j*(120) -192 + j*(-133) --127 + j*(59) --130 + j*(-279) -1 + j*(-224) --70 + j*(-42) -61 + j*(80) --13 + j*(-11) --8 + j*(-95) -132 + j*(-240) --215 + j*(-160) -191 + j*(133) -124 + j*(-373) --161 + j*(-139) -110 + j*(-134) --245 + j*(1) --267 + j*(103) --13 + j*(-384) -226 + j*(-58) -21 + j*(121) --45 + j*(-400) -120 + j*(76) -69 + j*(35) --111 + j*(40) -105 + j*(190) -164 + j*(161) --268 + j*(-40) -177 + j*(-25) --61 + j*(-80) -185 + j*(310) --110 + j*(141) -20 + j*(187) --299 + j*(-25) --24 + j*(326) --92 + j*(-335) -52 + j*(-324) --342 + j*(-267) --91 + j*(-10) -332 + j*(-119) -18 + j*(-219) -54 + j*(140) -333 + j*(237) --201 + j*(207) --99 + j*(294) --49 + j*(-26) -306 + j*(-37) --404 + j*(277) -22 + j*(-156) -348 + j*(-117) -62 + j*(197) -80 + j*(240) --317 + j*(402) -226 + j*(-252) --26 + j*(-31) --107 + j*(65) --45 + j*(7) --237 + j*(-146) --102 + j*(-73) --199 + j*(63) --196 + j*(-39) -68 + j*(50) -111 + j*(-71) -86 + j*(-13) --69 + j*(44) -163 + j*(-116) -181 + j*(-127) --115 + j*(527) -112 + j*(16) --135 + j*(122) -124 + j*(28) -140 + j*(-145) --149 + j*(-218) -51 + j*(-5) -66 + j*(315) -249 + j*(-198) -54 + j*(60) -283 + j*(227) -272 + j*(237) -228 + j*(53) -296 + j*(212) --255 + j*(-52) -252 + j*(93) -49 + j*(-134) -279 + j*(54) --21 + j*(-343) --116 + j*(206) --52 + j*(-47) -69 + j*(187) -21 + j*(93) --28 + j*(-166) --97 + j*(-161) -367 + j*(-90) --39 + j*(53) -400 + j*(92) -381 + j*(-169) --303 + j*(219) -2 + j*(58) -21 + j*(248) --160 + j*(-125) -379 + j*(-387) -62 + j*(-31) --126 + j*(-76) --17 + j*(47) -29 + j*(45) --286 + j*(-181) -21 + j*(103) --117 + j*(29) -86 + j*(386) --132 + j*(-129) -83 + j*(178) -243 + j*(-298) -144 + j*(-295) -111 + j*(-109) --201 + j*(168) -55 + j*(-192) --13 + j*(41) --129 + j*(147) --8 + j*(-37) --39 + j*(32) -28 + j*(90) -323 + j*(-245) -107 + j*(-77) --8 + j*(-421) -187 + j*(-118) --54 + j*(-160) --91 + j*(54) -215 + j*(267) -239 + j*(-159) -106 + j*(-174) --106 + j*(349) --153 + j*(33) -45 + j*(98) --145 + j*(134) --101 + j*(-190) --331 + j*(40) --167 + j*(-255) -129 + j*(-113) -112 + j*(250) -10 + j*(-317) -125 + j*(-106) -96 + j*(102) -238 + j*(-6) --108 + j*(222) --82 + j*(122) --453 + j*(-377) --97 + j*(139) -103 + j*(-56) --425 + j*(28) -164 + j*(154) -152 + j*(-62) -74 + j*(320) -85 + j*(-80) -146 + j*(-23) --291 + j*(-153) --5 + j*(-3) --155 + j*(23) -153 + j*(294) -59 + j*(-132) -5 + j*(153) -59 + j*(-105) -54 + j*(-325) -177 + j*(170) --223 + j*(-124) -183 + j*(-128) -119 + j*(-180) -332 + j*(71) --14 + j*(93) -199 + j*(81) --101 + j*(-75) -7 + j*(-35) --101 + j*(52) -219 + j*(-284) --102 + j*(-143) -16 + j*(-176) -132 + j*(-16) -76 + j*(-266) -24 + j*(-6) --81 + j*(8) --240 + j*(362) --54 + j*(-95) -490 + j*(-91) -201 + j*(-194) --127 + j*(-102) -48 + j*(4) -250 + j*(-54) -146 + j*(-409) -260 + j*(-20) --40 + j*(50) --119 + j*(-64) -319 + j*(-222) --88 + j*(-216) -157 + j*(191) -112 + j*(-34) --222 + j*(-145) --129 + j*(175) -71 + j*(134) -27 + j*(-133) --87 + j*(-340) --175 + j*(126) -76 + j*(54) --261 + j*(172) -64 + j*(-37) --10 + j*(-211) -30 + j*(169) -23 + j*(-247) --204 + j*(-54) -67 + j*(63) -191 + j*(-223) -22 + j*(454) --156 + j*(91) --45 + j*(-122) --23 + j*(-189) --31 + j*(139) -138 + j*(-201) --324 + j*(-299) --88 + j*(158) --8 + j*(-104) -93 + j*(-129) -112 + j*(-8) -75 + j*(-82) -279 + j*(182) -118 + j*(-400) --162 + j*(89) --398 + j*(58) -4 + j*(101) --133 + j*(-206) --42 + j*(-1) --276 + j*(322) --385 + j*(5) -56 + j*(43) -281 + j*(107) --91 + j*(70) -31 + j*(33) -57 + j*(4) -71 + j*(-126) -129 + j*(175) -565 + j*(-270) --211 + j*(40) --54 + j*(216) -57 + j*(-281) -255 + j*(-197) --21 + j*(190) -183 + j*(110) --123 + j*(46) -111 + j*(45) --381 + j*(100) --296 + j*(153) --214 + j*(-46) --221 + j*(-68) -348 + j*(231) -247 + j*(24) --38 + j*(263) --146 + j*(-361) -51 + j*(271) -146 + j*(-119) --86 + j*(-81) --163 + j*(-21) -92 + j*(70) -159 + j*(139) --301 + j*(54) --13 + j*(-272) --105 + j*(25) --95 + j*(-56) -222 + j*(54) -250 + j*(-56) -354 + j*(-152) -139 + j*(59) --126 + j*(-175) -332 + j*(-244) --88 + j*(-8) --214 + j*(-261) --282 + j*(-13) -75 + j*(49) --180 + j*(-13) --69 + j*(66) --161 + j*(-1) -51 + j*(-62) -26 + j*(-37) --54 + j*(323) -264 + j*(-8) --52 + j*(-44) -86 + j*(341) --48 + j*(-54) --469 + j*(167) --436 + j*(-108) --132 + j*(-14) --134 + j*(74) -364 + j*(258) -22 + j*(156) --40 + j*(293) -41 + j*(98) --83 + j*(-12) -117 + j*(59) -89 + j*(216) --9 + j*(146) -40 + j*(-132) -35 + j*(-151) --178 + j*(-33) --194 + j*(-57) --85 + j*(206) --134 + j*(256) -110 + j*(214) -204 + j*(-109) -236 + j*(-13) -113 + j*(-40) --409 + j*(52) --37 + j*(223) -139 + j*(61) --145 + j*(212) --97 + j*(161) -340 + j*(-211) --184 + j*(13) -235 + j*(-4) --237 + j*(-257) -81 + j*(49) -196 + j*(79) -84 + j*(131) -6 + j*(-95) --291 + j*(426) -221 + j*(89) --31 + j*(116) -74 + j*(260) --156 + j*(47) --261 + j*(-265) --8 + j*(-291) -23 + j*(129) -89 + j*(87) -71 + j*(-16) -217 + j*(293) --402 + j*(-98) --1 + j*(4) -84 + j*(-253) -39 + j*(108) -175 + j*(301) --257 + j*(81) --289 + j*(-86) --313 + j*(-76) -39 + j*(-79) -146 + j*(136) -218 + j*(33) --217 + j*(31) --11 + j*(237) --117 + j*(56) -130 + j*(100) -178 + j*(416) -99 + j*(84) -165 + j*(-202) -61 + j*(-320) --215 + j*(186) --78 + j*(220) --235 + j*(-151) --60 + j*(107) --40 + j*(45) --119 + j*(-298) -250 + j*(-164) --129 + j*(-186) -247 + j*(182) -52 + j*(238) --23 + j*(165) -122 + j*(78) -161 + j*(-262) --313 + j*(44) -1 + j*(-35) -1 + j*(-36) -13 + j*(-135) --223 + j*(-115) --320 + j*(303) --268 + j*(-66) --19 + j*(52) --12 + j*(-124) --28 + j*(42) -219 + j*(-94) --272 + j*(-265) --114 + j*(-81) --107 + j*(28) --129 + j*(-131) --139 + j*(-63) -55 + j*(-259) -241 + j*(-81) --159 + j*(43) --125 + j*(221) -119 + j*(-114) -95 + j*(-36) --213 + j*(-377) -109 + j*(-205) -332 + j*(69) -71 + j*(-182) --28 + j*(-100) -95 + j*(-33) -134 + j*(201) --81 + j*(245) --41 + j*(-175) --55 + j*(-212) -235 + j*(-14) -123 + j*(21) --86 + j*(207) --156 + j*(71) --115 + j*(363) -339 + j*(-28) --325 + j*(262) -188 + j*(-102) -112 + j*(189) -19 + j*(-39) -35 + j*(-77) -181 + j*(-13) --77 + j*(-12) -202 + j*(66) --254 + j*(-63) -150 + j*(131) --136 + j*(42) --238 + j*(-233) -467 + j*(-366) --125 + j*(202) --333 + j*(52) --27 + j*(-125) --224 + j*(4) --52 + j*(246) -362 + j*(-105) --151 + j*(-169) -175 + j*(36) --5 + j*(-147) --59 + j*(23) -222 + j*(86) --9 + j*(-178) -95 + j*(-159) --40 + j*(-3) -298 + j*(158) --94 + j*(354) -48 + j*(33) --42 + j*(-237) -120 + j*(115) --9 + j*(-30) -172 + j*(42) -158 + j*(153) --320 + j*(-88) -22 + j*(-382) --199 + j*(-37) -234 + j*(-310) --208 + j*(2) -40 + j*(16) -309 + j*(-85) -123 + j*(-172) -77 + j*(77) --30 + j*(135) --95 + j*(-40) -72 + j*(-25) --43 + j*(37) -237 + j*(-185) --68 + j*(-187) --298 + j*(55) -105 + j*(-116) -82 + j*(81) --107 + j*(-53) -18 + j*(156) --170 + j*(257) --93 + j*(128) -70 + j*(83) --8 + j*(-257) --46 + j*(-182) --496 + j*(-38) --16 + j*(-24) --5 + j*(-170) -152 + j*(-168) --338 + j*(-136) --75 + j*(104) -265 + j*(119) --146 + j*(231) --310 + j*(0) --7 + j*(-157) --48 + j*(-255) -254 + j*(-21) -134 + j*(-4) --101 + j*(146) --236 + j*(-372) --164 + j*(32) -122 + j*(177) --180 + j*(108) -57 + j*(-165) --6 + j*(255) --75 + j*(123) -13 + j*(100) --170 + j*(-28) --135 + j*(173) -83 + j*(151) --379 + j*(16) --8 + j*(44) --325 + j*(57) -186 + j*(129) -46 + j*(-37) --185 + j*(39) -45 + j*(8) --170 + j*(156) -95 + j*(231) -180 + j*(-313) --371 + j*(-122) --106 + j*(112) -23 + j*(303) --59 + j*(-170) -45 + j*(84) -62 + j*(169) --292 + j*(-88) -60 + j*(-78) --204 + j*(-129) --61 + j*(18) --118 + j*(-74) --98 + j*(227) -170 + j*(201) -86 + j*(254) -119 + j*(98) --173 + j*(129) --62 + j*(71) -7 + j*(-236) -216 + j*(161) --129 + j*(-50) --182 + j*(43) --54 + j*(-159) -113 + j*(-342) -107 + j*(-122) --175 + j*(-31) -30 + j*(112) -42 + j*(-136) -123 + j*(-122) -46 + j*(-36) -22 + j*(-10) -124 + j*(356) -297 + j*(-171) --27 + j*(284) -317 + j*(-117) --34 + j*(-349) -177 + j*(16) --259 + j*(112) --161 + j*(-250) --232 + j*(43) --240 + j*(-83) --162 + j*(370) --13 + j*(253) --77 + j*(-49) --6 + j*(-209) --88 + j*(219) --211 + j*(107) -147 + j*(25) --273 + j*(36) --139 + j*(-117) --177 + j*(52) -223 + j*(170) -139 + j*(-26) -168 + j*(-164) -124 + j*(143) -23 + j*(-224) --54 + j*(-113) -243 + j*(-158) --97 + j*(42) --169 + j*(-34) --30 + j*(110) -317 + j*(6) -173 + j*(317) --210 + j*(-268) --126 + j*(11) -56 + j*(-126) -78 + j*(-158) --82 + j*(133) --133 + j*(-240) --180 + j*(-79) --80 + j*(115) --25 + j*(-201) -371 + j*(11) --68 + j*(202) --231 + j*(-102) --69 + j*(-87) --294 + j*(327) --95 + j*(-16) --231 + j*(-69) -53 + j*(240) --58 + j*(84) --94 + j*(90) -141 + j*(176) --90 + j*(-110) --153 + j*(-4) --58 + j*(126) --67 + j*(13) -92 + j*(-43) --13 + j*(-36) --139 + j*(-202) --228 + j*(-331) -180 + j*(34) --257 + j*(458) --211 + j*(111) --337 + j*(83) -40 + j*(-76) -40 + j*(-325) --4 + j*(-22) --124 + j*(2) -112 + j*(-317) -204 + j*(82) --4 + j*(-29) -112 + j*(-193) --70 + j*(-98) --99 + j*(144) -241 + j*(3) --74 + j*(-40) -224 + j*(148) -216 + j*(69) -36 + j*(-23) --28 + j*(-166) -40 + j*(157) -198 + j*(52) --225 + j*(69) -77 + j*(-260) --32 + j*(-78) --313 + j*(-35) -138 + j*(28) --10 + j*(102) -92 + j*(-91) -267 + j*(-384) -148 + j*(211) --44 + j*(170) --30 + j*(207) -125 + j*(51) -175 + j*(-47) --23 + j*(-171) --165 + j*(-109) -176 + j*(83) --62 + j*(148) -124 + j*(-119) --121 + j*(-276) -54 + j*(-243) --163 + j*(-109) -1 + j*(-34) --83 + j*(182) -35 + j*(146) -322 + j*(53) --175 + j*(34) --156 + j*(-173) -83 + j*(428) -195 + j*(-110) -70 + j*(-187) -259 + j*(107) -99 + j*(233) --73 + j*(-90) --73 + j*(52) -48 + j*(327) -108 + j*(-49) -218 + j*(-158) --22 + j*(-165) -296 + j*(-61) --22 + j*(91) --109 + j*(92) -26 + j*(-6) --75 + j*(41) -52 + j*(187) -82 + j*(184) -42 + j*(116) --71 + j*(228) --72 + j*(190) --218 + j*(-179) -156 + j*(284) --151 + j*(0) -191 + j*(-107) --35 + j*(-240) -245 + j*(-145) --96 + j*(-74) -146 + j*(168) --59 + j*(-107) --114 + j*(115) -60 + j*(-71) -93 + j*(5) -46 + j*(142) --16 + j*(63) --232 + j*(151) --312 + j*(-18) -182 + j*(-24) -227 + j*(221) --200 + j*(-145) -251 + j*(254) -25 + j*(-163) --110 + j*(-184) --256 + j*(173) --83 + j*(56) -184 + j*(-23) --12 + j*(-21) --228 + j*(15) -35 + j*(-117) --6 + j*(25) -77 + j*(-12) --243 + j*(-4) -29 + j*(-12) --221 + j*(71) --30 + j*(40) -100 + j*(-631) --146 + j*(-156) -310 + j*(94) -33 + j*(76) --184 + j*(168) --2 + j*(56) --76 + j*(57) --37 + j*(93) -266 + j*(3) -127 + j*(-191) -284 + j*(-4) -63 + j*(248) -327 + j*(-94) --276 + j*(119) --351 + j*(2) -379 + j*(6) --80 + j*(163) -135 + j*(59) --156 + j*(0) -228 + j*(-18) -566 + j*(-95) -375 + j*(-13) --68 + j*(-289) --250 + j*(-154) -98 + j*(79) --4 + j*(0) --165 + j*(153) --36 + j*(285) -70 + j*(-14) --155 + j*(74) -45 + j*(8) -123 + j*(14) --197 + j*(232) --250 + j*(58) --124 + j*(319) -125 + j*(0) -10 + j*(-142) -137 + j*(-70) --180 + j*(146) -280 + j*(77) --252 + j*(-92) -35 + j*(13) --135 + j*(366) -104 + j*(37) --84 + j*(-117) -11 + j*(-238) -74 + j*(-181) -134 + j*(21) --64 + j*(-122) --344 + j*(-146) -194 + j*(-158) --59 + j*(-111) --286 + j*(-121) --225 + j*(71) --93 + j*(-153) -94 + j*(21) -1 + j*(323) -1 + j*(138) --59 + j*(-13) -5 + j*(-44) --55 + j*(47) --45 + j*(126) --136 + j*(105) --420 + j*(-415) --1 + j*(-133) --259 + j*(-263) --106 + j*(-181) --112 + j*(-18) -18 + j*(318) --173 + j*(162) --166 + j*(7) -11 + j*(-161) -326 + j*(3) -90 + j*(301) --198 + j*(-94) -151 + j*(-48) --272 + j*(103) -97 + j*(15) --125 + j*(52) -378 + j*(-346) -40 + j*(-30) --98 + j*(-186) -207 + j*(339) -42 + j*(-130) --16 + j*(13) --33 + j*(49) -140 + j*(193) --49 + j*(233) --106 + j*(-242) --207 + j*(-18) -177 + j*(-38) --520 + j*(-117) -60 + j*(40) --327 + j*(279) -342 + j*(-58) --39 + j*(-69) --127 + j*(-42) -235 + j*(-59) --267 + j*(46) -71 + j*(130) --88 + j*(45) -282 + j*(-4) -219 + j*(-82) --122 + j*(-25) --76 + j*(169) -284 + j*(124) -4 + j*(-43) -83 + j*(-349) -43 + j*(342) -31 + j*(-173) -345 + j*(250) --18 + j*(177) --81 + j*(155) -355 + j*(156) --93 + j*(-11) -141 + j*(3) --83 + j*(77) -340 + j*(-164) --117 + j*(59) -94 + j*(189) -127 + j*(-243) --284 + j*(-161) --19 + j*(-133) -182 + j*(86) --153 + j*(97) --16 + j*(-69) -197 + j*(-16) --18 + j*(29) -8 + j*(-72) --95 + j*(312) --76 + j*(-127) -93 + j*(-103) --127 + j*(16) -78 + j*(329) --69 + j*(111) -182 + j*(192) -43 + j*(-180) --77 + j*(81) --91 + j*(-274) --136 + j*(57) -29 + j*(-122) -291 + j*(-81) --227 + j*(127) --165 + j*(227) -61 + j*(-100) --80 + j*(-31) --211 + j*(-145) --168 + j*(-113) --40 + j*(68) -259 + j*(121) -111 + j*(-69) -245 + j*(47) -11 + j*(-61) --136 + j*(104) -3 + j*(-161) --105 + j*(-15) -122 + j*(-453) --36 + j*(-18) --148 + j*(243) -78 + j*(-107) -181 + j*(276) -276 + j*(-42) -179 + j*(-117) --103 + j*(397) -250 + j*(-53) --25 + j*(184) -108 + j*(-56) -171 + j*(-1) -217 + j*(178) --149 + j*(-189) --134 + j*(-218) -76 + j*(402) --10 + j*(139) -100 + j*(236) -61 + j*(-177) -27 + j*(9) -151 + j*(38) --110 + j*(-92) -222 + j*(-115) -118 + j*(-158) -94 + j*(118) -494 + j*(197) --16 + j*(-27) --307 + j*(-13) --81 + j*(262) -231 + j*(192) -278 + j*(21) -56 + j*(-35) --328 + j*(316) -130 + j*(32) --37 + j*(209) -306 + j*(51) -113 + j*(114) --228 + j*(-101) --45 + j*(22) --106 + j*(-86) --188 + j*(-74) -124 + j*(57) --70 + j*(-83) --216 + j*(-23) --87 + j*(-109) -97 + j*(-263) -78 + j*(90) --15 + j*(256) --103 + j*(350) -21 + j*(-25) -32 + j*(115) -76 + j*(-270) -190 + j*(-41) -8 + j*(195) -127 + j*(-100) --8 + j*(-132) -253 + j*(-117) --100 + j*(5) --57 + j*(-319) --18 + j*(82) -163 + j*(231) --127 + j*(-271) --74 + j*(-243) -39 + j*(-278) --88 + j*(179) --100 + j*(-33) --373 + j*(-333) --182 + j*(-299) --117 + j*(-78) -34 + j*(-185) --117 + j*(155) --28 + j*(56) --161 + j*(-70) --97 + j*(-310) --30 + j*(13) --254 + j*(33) -119 + j*(8) -333 + j*(46) --383 + j*(27) -83 + j*(188) -73 + j*(-217) -59 + j*(60) --166 + j*(266) --177 + j*(123) --356 + j*(-55) --339 + j*(-30) --143 + j*(49) -105 + j*(-224) --173 + j*(305) --35 + j*(202) --185 + j*(-152) --221 + j*(132) --244 + j*(-58) -104 + j*(276) --182 + j*(21) -117 + j*(-134) -285 + j*(-66) -33 + j*(-86) -91 + j*(-28) -6 + j*(50) -83 + j*(-8) --185 + j*(60) --32 + j*(-94) --179 + j*(9) --323 + j*(136) -15 + j*(-417) -197 + j*(-105) --71 + j*(74) -6 + j*(-117) -184 + j*(407) -123 + j*(-37) -57 + j*(12) --52 + j*(168) --188 + j*(-119) -28 + j*(-129) --78 + j*(-1) --104 + j*(-83) -1 + j*(-223) --468 + j*(42) -157 + j*(52) --144 + j*(-72) -75 + j*(296) -45 + j*(-285) --221 + j*(301) --103 + j*(163) --341 + j*(-457) -105 + j*(23) --23 + j*(-88) --264 + j*(-552) -81 + j*(4) --274 + j*(-131) -214 + j*(-18) -151 + j*(-214) --1 + j*(-205) -103 + j*(-49) -81 + j*(-8) --80 + j*(16) -246 + j*(-183) -136 + j*(-100) -35 + j*(-69) --217 + j*(254) -252 + j*(-156) --47 + j*(-160) --162 + j*(167) --148 + j*(-201) -265 + j*(-240) --141 + j*(-8) -35 + j*(33) --99 + j*(-95) --4 + j*(124) -65 + j*(-206) --175 + j*(279) --1 + j*(114) --52 + j*(71) --103 + j*(47) --164 + j*(-41) -206 + j*(216) --148 + j*(19) --161 + j*(-187) --200 + j*(223) -131 + j*(238) -18 + j*(101) -229 + j*(22) -71 + j*(53) -509 + j*(-293) -139 + j*(161) --322 + j*(180) -119 + j*(196) -12 + j*(103) -10 + j*(-187) -104 + j*(-28) -82 + j*(50) -86 + j*(125) -117 + j*(59) --225 + j*(129) -167 + j*(-177) --125 + j*(-100) --178 + j*(-124) --144 + j*(-262) -457 + j*(-237) --267 + j*(22) -240 + j*(22) -155 + j*(89) --6 + j*(-361) -266 + j*(-358) --180 + j*(110) --73 + j*(69) --42 + j*(93) --257 + j*(-151) -3 + j*(141) -192 + j*(356) -26 + j*(-76) -103 + j*(340) -83 + j*(70) -75 + j*(-245) -206 + j*(340) --144 + j*(360) -344 + j*(76) --74 + j*(325) --7 + j*(208) --238 + j*(-206) -25 + j*(83) -57 + j*(-286) --82 + j*(232) -251 + j*(-76) --218 + j*(-234) --170 + j*(-219) --75 + j*(-252) --112 + j*(259) -24 + j*(31) --226 + j*(59) --67 + j*(-4) --344 + j*(-240) --86 + j*(143) -37 + j*(-59) -54 + j*(-173) --264 + j*(-52) -78 + j*(104) --337 + j*(-103) -115 + j*(-144) -228 + j*(4) -93 + j*(-54) -15 + j*(-245) -118 + j*(-70) --8 + j*(-69) -195 + j*(-202) -110 + j*(172) --214 + j*(-326) --74 + j*(199) -81 + j*(124) -59 + j*(141) -88 + j*(-178) --28 + j*(22) -132 + j*(144) -71 + j*(-90) -101 + j*(-243) --191 + j*(32) --12 + j*(-52) -134 + j*(18) --416 + j*(338) -98 + j*(-92) --122 + j*(-18) --123 + j*(-100) --405 + j*(86) -59 + j*(260) --272 + j*(201) --129 + j*(320) --214 + j*(35) --24 + j*(9) --137 + j*(88) --46 + j*(-113) --99 + j*(105) --4 + j*(51) --59 + j*(-19) -267 + j*(56) -77 + j*(-30) -66 + j*(61) -6 + j*(-23) -0 + j*(198) --4 + j*(-117) --58 + j*(5) --141 + j*(143) --4 + j*(100) --150 + j*(-117) -88 + j*(-301) --90 + j*(-31) -247 + j*(58) --84 + j*(-112) -387 + j*(-145) --50 + j*(-57) --117 + j*(-25) --103 + j*(102) -113 + j*(294) -248 + j*(142) --61 + j*(-134) --152 + j*(129) -106 + j*(-170) --332 + j*(-23) --168 + j*(206) -240 + j*(36) --196 + j*(-146) --400 + j*(67) -40 + j*(-26) -110 + j*(213) --288 + j*(252) -53 + j*(206) -253 + j*(-489) --428 + j*(390) --426 + j*(339) -162 + j*(-463) -278 + j*(159) --35 + j*(426) --375 + j*(323) --243 + j*(186) -230 + j*(325) --340 + j*(-334) --193 + j*(148) --640 + j*(75) --14 + j*(106) --49 + j*(233) -93 + j*(225) --23 + j*(-235) --560 + j*(-476) --494 + j*(412) -302 + j*(424) -122 + j*(255) --317 + j*(320) --47 + j*(-134) --411 + j*(412) --241 + j*(107) --639 + j*(-566) -427 + j*(-136) --165 + j*(-217) -515 + j*(471) --91 + j*(-151) -405 + j*(221) -139 + j*(-260) --82 + j*(151) -228 + j*(514) --165 + j*(231) -425 + j*(-11) --210 + j*(117) --475 + j*(247) --291 + j*(500) -18 + j*(-106) -443 + j*(57) --283 + j*(348) -226 + j*(-305) --211 + j*(-33) -412 + j*(-233) --272 + j*(237) --378 + j*(8) -299 + j*(-136) -182 + j*(-98) --489 + j*(183) -41 + j*(286) --64 + j*(226) -102 + j*(351) -375 + j*(471) --121 + j*(252) -310 + j*(-366) -194 + j*(-442) -67 + j*(-332) -190 + j*(-188) -467 + j*(-81) --313 + j*(-344) --49 + j*(-161) --589 + j*(85) --91 + j*(187) -127 + j*(11) --212 + j*(551) -350 + j*(7) -170 + j*(327) --387 + j*(-363) --190 + j*(-612) -207 + j*(319) --121 + j*(315) --401 + j*(161) --432 + j*(209) --467 + j*(-334) -276 + j*(90) -185 + j*(-222) --506 + j*(490) --455 + j*(-293) --49 + j*(-448) -224 + j*(293) -427 + j*(-559) --267 + j*(-164) --23 + j*(-156) --324 + j*(-267) --215 + j*(-33) -98 + j*(-173) --209 + j*(-255) --197 + j*(431) -238 + j*(367) -47 + j*(-198) --308 + j*(-1) --173 + j*(119) --134 + j*(-357) --186 + j*(71) -198 + j*(-59) -66 + j*(298) --412 + j*(45) -416 + j*(426) -127 + j*(231) -285 + j*(-231) -81 + j*(-380) -228 + j*(52) --291 + j*(436) --28 + j*(91) -331 + j*(-356) --12 + j*(800) --144 + j*(303) --334 + j*(206) -316 + j*(250) -272 + j*(-503) --192 + j*(-511) -298 + j*(-80) -23 + j*(-566) -480 + j*(-347) -222 + j*(-330) -148 + j*(256) -505 + j*(-419) -270 + j*(-203) -409 + j*(-450) --115 + j*(325) --101 + j*(-471) --74 + j*(23) --163 + j*(-351) --3 + j*(354) -8 + j*(-183) --196 + j*(132) -329 + j*(-443) -342 + j*(334) --338 + j*(-366) --143 + j*(-636) -464 + j*(-245) --168 + j*(204) -216 + j*(252) -252 + j*(-243) --81 + j*(342) --196 + j*(233) -277 + j*(-301) -367 + j*(-276) -59 + j*(58) -163 + j*(398) --68 + j*(144) -47 + j*(335) -504 + j*(-647) --169 + j*(-404) -343 + j*(-343) --452 + j*(90) --189 + j*(175) --70 + j*(322) -354 + j*(-152) -422 + j*(262) --247 + j*(-209) -569 + j*(157) -75 + j*(-52) --169 + j*(-175) --334 + j*(16) -177 + j*(605) -434 + j*(-502) --339 + j*(37) -57 + j*(-246) -437 + j*(249) --235 + j*(-141) --247 + j*(-356) --54 + j*(-366) --305 + j*(-142) --237 + j*(164) -8 + j*(-373) -204 + j*(107) --617 + j*(136) -429 + j*(-337) --337 + j*(-326) -506 + j*(477) -161 + j*(-22) -149 + j*(231) -202 + j*(-274) --176 + j*(-391) --252 + j*(-400) --28 + j*(167) -256 + j*(-452) -419 + j*(188) --142 + j*(-805) -417 + j*(-392) -10 + j*(197) --335 + j*(105) --114 + j*(149) --170 + j*(265) --387 + j*(-233) --444 + j*(-151) -119 + j*(451) -270 + j*(422) -591 + j*(-421) --250 + j*(-196) -62 + j*(-338) -266 + j*(28) --476 + j*(69) -71 + j*(-97) --52 + j*(-268) --136 + j*(-214) -223 + j*(633) --518 + j*(220) -595 + j*(184) -160 + j*(124) --304 + j*(-202) -246 + j*(187) -64 + j*(300) -368 + j*(108) -255 + j*(-130) --220 + j*(-389) --424 + j*(41) -508 + j*(16) --334 + j*(-446) --89 + j*(81) --685 + j*(169) -273 + j*(-25) -110 + j*(374) -355 + j*(250) --29 + j*(-200) --298 + j*(-629) --508 + j*(144) -319 + j*(-343) -103 + j*(-57) --59 + j*(373) -282 + j*(-14) --102 + j*(350) -147 + j*(14) --185 + j*(35) --260 + j*(220) --337 + j*(-359) -357 + j*(182) -192 + j*(-279) --293 + j*(-5) -257 + j*(217) -247 + j*(-105) --5 + j*(-358) -252 + j*(-95) -69 + j*(-534) --95 + j*(-283) -147 + j*(-37) -170 + j*(409) -394 + j*(452) --110 + j*(-421) --257 + j*(190) --450 + j*(-209) -77 + j*(-546) -161 + j*(16) -337 + j*(-32) -543 + j*(145) --306 + j*(-438) --64 + j*(159) --234 + j*(-197) --445 + j*(-51) --208 + j*(-62) --275 + j*(228) --445 + j*(-221) -524 + j*(-37) -204 + j*(516) -246 + j*(-404) -624 + j*(-243) --118 + j*(264) -61 + j*(194) --132 + j*(-127) -220 + j*(298) --222 + j*(-282) -167 + j*(-286) -330 + j*(466) -501 + j*(0) -620 + j*(414) -134 + j*(-269) --212 + j*(193) -373 + j*(-335) --107 + j*(40) -342 + j*(-279) --286 + j*(138) -190 + j*(238) --321 + j*(-240) --409 + j*(-247) -371 + j*(505) -247 + j*(272) --223 + j*(-23) -111 + j*(349) --177 + j*(306) -466 + j*(92) --267 + j*(322) -301 + j*(231) -460 + j*(-168) --155 + j*(-254) --320 + j*(-181) -50 + j*(-330) -283 + j*(-357) -163 + j*(-354) -67 + j*(379) --105 + j*(-199) -245 + j*(-296) -387 + j*(371) -56 + j*(57) -453 + j*(279) --324 + j*(33) --327 + j*(-474) --238 + j*(308) --28 + j*(-187) --252 + j*(-229) -165 + j*(194) -509 + j*(434) --337 + j*(518) -3 + j*(-243) -275 + j*(378) -237 + j*(-86) -245 + j*(192) -225 + j*(-257) --325 + j*(-468) --482 + j*(291) --266 + j*(63) --496 + j*(315) -408 + j*(-185) --536 + j*(102) --320 + j*(-224) --404 + j*(16) -302 + j*(246) --263 + j*(19) -308 + j*(-209) -8 + j*(363) --605 + j*(-448) -266 + j*(347) -602 + j*(-82) --276 + j*(-238) -296 + j*(111) -293 + j*(-229) --233 + j*(-84) -186 + j*(-148) -193 + j*(365) -99 + j*(-303) -117 + j*(454) --98 + j*(288) --508 + j*(-424) --370 + j*(650) -324 + j*(375) -415 + j*(-221) --211 + j*(40) -258 + j*(-7) --519 + j*(-225) --303 + j*(112) -247 + j*(-286) -303 + j*(-456) -179 + j*(244) -29 + j*(-155) -321 + j*(458) -144 + j*(226) --195 + j*(-434) --52 + j*(-276) --339 + j*(203) --531 + j*(35) --82 + j*(57) --717 + j*(-362) --407 + j*(227) -257 + j*(343) -140 + j*(-224) -403 + j*(195) --177 + j*(469) -158 + j*(-312) -15 + j*(-269) --363 + j*(262) --36 + j*(-339) -342 + j*(-153) --56 + j*(696) -298 + j*(197) --93 + j*(134) --14 + j*(501) -511 + j*(228) --98 + j*(269) -235 + j*(417) -274 + j*(-367) --327 + j*(228) --27 + j*(148) -404 + j*(-207) -411 + j*(332) -449 + j*(276) -716 + j*(725) -42 + j*(429) --163 + j*(527) -156 + j*(274) --593 + j*(-375) -496 + j*(419) -277 + j*(-330) -513 + j*(-36) -175 + j*(-386) -134 + j*(-376) --95 + j*(-299) --179 + j*(57) -465 + j*(416) -342 + j*(317) -158 + j*(47) --141 + j*(248) --173 + j*(206) --394 + j*(119) -392 + j*(136) --315 + j*(195) -335 + j*(450) -176 + j*(8) -613 + j*(-317) -150 + j*(-186) --403 + j*(-643) -133 + j*(-279) -41 + j*(-164) -276 + j*(-46) -298 + j*(396) --260 + j*(-488) --390 + j*(114) -32 + j*(375) --470 + j*(216) -585 + j*(298) --443 + j*(-373) -251 + j*(306) --372 + j*(318) --371 + j*(408) --92 + j*(-80) --286 + j*(14) --351 + j*(59) --21 + j*(366) --197 + j*(-182) --267 + j*(-47) -177 + j*(-265) --443 + j*(-212) -470 + j*(0) -90 + j*(315) --68 + j*(-222) --506 + j*(-289) --236 + j*(-293) -131 + j*(-98) --257 + j*(174) --37 + j*(-494) --486 + j*(35) -195 + j*(-247) -325 + j*(-836) --73 + j*(-497) --91 + j*(531) -642 + j*(-362) -344 + j*(124) --120 + j*(-199) --50 + j*(-488) -1 + j*(-345) -285 + j*(103) -206 + j*(452) -176 + j*(433) --323 + j*(427) --442 + j*(340) --362 + j*(-361) -417 + j*(-184) --148 + j*(251) --289 + j*(-111) --426 + j*(-202) --597 + j*(-365) -409 + j*(199) -227 + j*(339) --284 + j*(-69) -282 + j*(-156) -40 + j*(473) --271 + j*(-76) --228 + j*(-424) --44 + j*(-64) -28 + j*(371) -494 + j*(-400) --192 + j*(368) -199 + j*(211) --148 + j*(-41) -77 + j*(-412) -13 + j*(139) -350 + j*(-71) -40 + j*(117) --59 + j*(320) -240 + j*(-369) -193 + j*(180) -25 + j*(-484) -416 + j*(-252) -323 + j*(-39) -201 + j*(-394) --221 + j*(351) -375 + j*(-190) -249 + j*(562) -197 + j*(-238) -235 + j*(336) -296 + j*(-149) --493 + j*(-477) -310 + j*(-543) -495 + j*(38) --320 + j*(308) --496 + j*(130) --392 + j*(-78) --478 + j*(103) --346 + j*(-525) --134 + j*(-368) --247 + j*(-150) --472 + j*(-18) --354 + j*(40) -349 + j*(131) --284 + j*(312) -308 + j*(189) -67 + j*(-427) --1 + j*(-159) -362 + j*(-454) -219 + j*(262) --53 + j*(-28) --501 + j*(-225) --359 + j*(547) -369 + j*(315) --344 + j*(-361) --492 + j*(403) -500 + j*(-291) -260 + j*(191) -194 + j*(-170) -324 + j*(280) -595 + j*(120) -185 + j*(123) -222 + j*(670) --309 + j*(219) --237 + j*(-138) -338 + j*(-388) --223 + j*(100) --140 + j*(-430) -685 + j*(115) -339 + j*(-9) --100 + j*(-745) --561 + j*(-101) -360 + j*(446) -191 + j*(-467) --243 + j*(-378) --107 + j*(-345) -21 + j*(620) --223 + j*(-322) -409 + j*(-306) --23 + j*(499) --259 + j*(-576) -493 + j*(658) -180 + j*(118) --378 + j*(198) -378 + j*(-53) --554 + j*(-61) --305 + j*(305) -95 + j*(415) -455 + j*(-305) --275 + j*(-77) -390 + j*(-62) --15 + j*(151) --238 + j*(191) --94 + j*(390) -369 + j*(262) -441 + j*(67) -439 + j*(-121) -315 + j*(66) -282 + j*(216) --193 + j*(-280) --194 + j*(625) --240 + j*(231) --228 + j*(68) -245 + j*(144) --467 + j*(64) -23 + j*(523) -46 + j*(-216) --248 + j*(390) -98 + j*(462) --378 + j*(329) -410 + j*(211) --81 + j*(277) -293 + j*(-16) -204 + j*(-506) --78 + j*(151) --88 + j*(455) -242 + j*(-62) --426 + j*(-105) --320 + j*(221) -84 + j*(-386) -398 + j*(565) -50 + j*(248) --254 + j*(-37) --179 + j*(479) --59 + j*(30) --225 + j*(253) -630 + j*(-185) --76 + j*(-363) -136 + j*(-498) -289 + j*(-79) -315 + j*(-177) -367 + j*(60) --131 + j*(-190) --482 + j*(-127) --68 + j*(220) -204 + j*(16) --175 + j*(45) -421 + j*(180) -231 + j*(-324) -93 + j*(334) --344 + j*(-599) --257 + j*(-276) --134 + j*(-98) -384 + j*(-203) -290 + j*(-177) --82 + j*(-226) --367 + j*(-1) -154 + j*(-307) --155 + j*(576) -216 + j*(279) -229 + j*(196) -35 + j*(138) --52 + j*(-210) -24 + j*(231) -153 + j*(-117) --125 + j*(-174) -23 + j*(-64) --96 + j*(-199) --167 + j*(16) -158 + j*(93) --180 + j*(-331) --42 + j*(-5) -6 + j*(521) --161 + j*(197) --6 + j*(-6) -268 + j*(107) --275 + j*(156) -245 + j*(-13) --52 + j*(-217) --221 + j*(355) -84 + j*(-42) -31 + j*(-204) --117 + j*(523) -211 + j*(268) --86 + j*(104) --181 + j*(-62) --45 + j*(-198) -141 + j*(82) --373 + j*(122) --151 + j*(5) --33 + j*(-191) -69 + j*(21) --124 + j*(30) --153 + j*(-206) --49 + j*(-235) --246 + j*(-214) --224 + j*(-144) --77 + j*(-115) --242 + j*(-233) -56 + j*(127) --137 + j*(-156) --108 + j*(-163) --60 + j*(-140) --91 + j*(73) --85 + j*(-101) --141 + j*(30) --144 + j*(34) -82 + j*(-5) -52 + j*(187) --285 + j*(-59) -62 + j*(271) --29 + j*(-113) --1 + j*(225) -101 + j*(-23) --143 + j*(196) --168 + j*(158) --211 + j*(-158) -71 + j*(-28) --115 + j*(-99) --49 + j*(-183) --58 + j*(8) --187 + j*(303) --6 + j*(-127) -188 + j*(-136) --66 + j*(-156) -134 + j*(-123) --78 + j*(41) --134 + j*(-218) --33 + j*(194) --33 + j*(-91) -15 + j*(326) -187 + j*(336) -9 + j*(21) -143 + j*(-202) -64 + j*(388) --179 + j*(-59) -149 + j*(-228) -62 + j*(255) --161 + j*(-35) --98 + j*(-286) --282 + j*(243) --2 + j*(112) --168 + j*(-325) --197 + j*(180) -182 + j*(-438) --193 + j*(-105) -103 + j*(-26) -168 + j*(135) --91 + j*(266) --94 + j*(-79) -165 + j*(228) -215 + j*(-136) --76 + j*(-318) --177 + j*(-263) --272 + j*(156) -337 + j*(-240) -310 + j*(95) -116 + j*(-1) -243 + j*(-195) -223 + j*(-48) --231 + j*(-1) -16 + j*(21) --153 + j*(66) -16 + j*(176) --52 + j*(136) -144 + j*(-22) -89 + j*(-197) -161 + j*(252) --122 + j*(-67) --258 + j*(127) --168 + j*(-146) --155 + j*(-39) -101 + j*(303) -60 + j*(-25) --305 + j*(67) --253 + j*(-231) -91 + j*(-173) -71 + j*(81) -23 + j*(186) --260 + j*(208) --2 + j*(149) --95 + j*(-175) -21 + j*(204) -402 + j*(-2) --8 + j*(-16) --175 + j*(150) -45 + j*(-235) -200 + j*(260) --375 + j*(-325) -179 + j*(166) -152 + j*(246) -6 + j*(80) -212 + j*(-17) --207 + j*(125) --6 + j*(12) -119 + j*(61) --115 + j*(320) -35 + j*(342) --184 + j*(-132) -62 + j*(-43) --151 + j*(125) -117 + j*(-96) -2 + j*(59) --90 + j*(-66) --18 + j*(239) --175 + j*(-296) -112 + j*(-147) -68 + j*(92) -61 + j*(-134) -8 + j*(-170) -59 + j*(225) -150 + j*(135) --108 + j*(-182) -120 + j*(340) --10 + j*(-316) -54 + j*(4) --40 + j*(29) -7 + j*(58) --280 + j*(143) --206 + j*(197) --183 + j*(181) --90 + j*(177) --115 + j*(26) --42 + j*(168) --34 + j*(-195) -32 + j*(125) -272 + j*(-323) --118 + j*(22) -125 + j*(-72) --164 + j*(296) -260 + j*(37) -133 + j*(228) -30 + j*(-123) -90 + j*(167) -39 + j*(83) -63 + j*(445) -7 + j*(-14) --21 + j*(83) --139 + j*(302) --600 + j*(137) --149 + j*(-34) -305 + j*(-392) -208 + j*(151) -26 + j*(16) -135 + j*(-170) --183 + j*(215) --78 + j*(1) --131 + j*(206) -202 + j*(356) -187 + j*(-204) -147 + j*(-86) -283 + j*(107) -30 + j*(-57) -182 + j*(36) --154 + j*(-84) -24 + j*(36) -124 + j*(52) --237 + j*(114) --218 + j*(39) --40 + j*(-302) --456 + j*(4) -136 + j*(63) --20 + j*(33) -81 + j*(-118) --52 + j*(140) -46 + j*(56) -146 + j*(-45) --85 + j*(-44) -33 + j*(-86) --76 + j*(-269) -143 + j*(91) --121 + j*(23) -12 + j*(93) --57 + j*(-215) -47 + j*(-370) -317 + j*(22) --103 + j*(16) -179 + j*(-135) -57 + j*(0) --30 + j*(88) -131 + j*(-74) -207 + j*(-72) --234 + j*(179) --226 + j*(-16) -226 + j*(161) -143 + j*(108) --95 + j*(-100) --24 + j*(-88) -380 + j*(102) -187 + j*(57) --23 + j*(188) -174 + j*(-252) -93 + j*(498) -194 + j*(196) -72 + j*(-33) --112 + j*(20) --106 + j*(-163) --93 + j*(-49) -98 + j*(100) --79 + j*(-144) --322 + j*(-298) --160 + j*(-301) -144 + j*(-13) -262 + j*(-20) --250 + j*(-38) -59 + j*(-44) --1 + j*(219) -234 + j*(-99) --3 + j*(-152) -160 + j*(-97) -359 + j*(152) --6 + j*(-20) --209 + j*(183) --36 + j*(192) --5 + j*(74) --171 + j*(-285) -11 + j*(49) --6 + j*(103) -18 + j*(147) --27 + j*(161) -4 + j*(-77) -193 + j*(-27) -81 + j*(89) --20 + j*(140) --253 + j*(-40) -246 + j*(104) -83 + j*(87) -160 + j*(-54) -277 + j*(4) -129 + j*(-228) -89 + j*(-37) -222 + j*(-259) -4 + j*(-252) --135 + j*(-66) --7 + j*(228) -190 + j*(133) --67 + j*(-235) -157 + j*(-184) -126 + j*(-25) --321 + j*(46) --291 + j*(-25) --365 + j*(-303) -83 + j*(-93) --286 + j*(77) --1 + j*(-198) --246 + j*(-414) -64 + j*(-129) -142 + j*(105) -188 + j*(-168) --139 + j*(-209) --58 + j*(330) --16 + j*(-140) --33 + j*(157) --77 + j*(-275) --151 + j*(-147) --37 + j*(-271) -206 + j*(254) -419 + j*(39) -156 + j*(-215) --33 + j*(86) -164 + j*(-355) --202 + j*(231) --162 + j*(-66) --112 + j*(-197) --72 + j*(-170) --66 + j*(-123) -70 + j*(245) --182 + j*(-83) -173 + j*(-288) -148 + j*(158) -38 + j*(324) -67 + j*(-69) -18 + j*(-21) -49 + j*(-88) -54 + j*(-108) --49 + j*(200) --228 + j*(-81) --436 + j*(-100) --21 + j*(-150) --58 + j*(-40) -368 + j*(-151) --32 + j*(-195) -30 + j*(-35) -190 + j*(21) -191 + j*(-153) --322 + j*(95) --42 + j*(-115) -103 + j*(-181) --110 + j*(183) -76 + j*(-199) --103 + j*(285) -81 + j*(271) -214 + j*(81) -10 + j*(6) -19 + j*(7) -149 + j*(42) --22 + j*(10) -211 + j*(-118) -126 + j*(-46) -276 + j*(163) -86 + j*(155) --108 + j*(19) --16 + j*(-174) -104 + j*(-542) -70 + j*(125) -168 + j*(128) --215 + j*(305) --2 + j*(35) --87 + j*(150) -50 + j*(-389) -111 + j*(136) --211 + j*(-159) --20 + j*(-172) -240 + j*(-195) -205 + j*(57) --98 + j*(43) -194 + j*(-65) --37 + j*(153) -30 + j*(123) --52 + j*(29) --266 + j*(8) --146 + j*(-105) -158 + j*(15) -69 + j*(-259) -304 + j*(176) -96 + j*(160) --39 + j*(-62) -5 + j*(80) --24 + j*(214) -152 + j*(61) -119 + j*(-291) --44 + j*(168) -48 + j*(431) --17 + j*(66) --4 + j*(264) --88 + j*(33) --160 + j*(-226) --238 + j*(-113) -42 + j*(-112) -75 + j*(30) -130 + j*(-27) -100 + j*(175) -106 + j*(-87) --320 + j*(-256) -122 + j*(-37) --141 + j*(-22) -80 + j*(-106) -301 + j*(-71) -117 + j*(-21) -93 + j*(419) -46 + j*(-291) --59 + j*(-177) --76 + j*(47) --64 + j*(-56) --12 + j*(74) --79 + j*(-18) -214 + j*(-89) -122 + j*(-144) --142 + j*(-150) --199 + j*(-298) -13 + j*(-134) --366 + j*(21) --2 + j*(-26) --30 + j*(139) --328 + j*(-211) --141 + j*(235) -253 + j*(-21) --219 + j*(-209) --71 + j*(-62) -82 + j*(-146) --127 + j*(261) --319 + j*(-255) --121 + j*(86) -585 + j*(32) --54 + j*(-60) -282 + j*(58) --122 + j*(221) -84 + j*(110) --153 + j*(1) -44 + j*(209) -229 + j*(110) -313 + j*(69) -202 + j*(-211) -39 + j*(21) -194 + j*(177) -209 + j*(69) --30 + j*(-167) -127 + j*(38) --177 + j*(11) --41 + j*(86) --15 + j*(243) -78 + j*(11) --79 + j*(-228) --116 + j*(-86) -23 + j*(47) -383 + j*(73) -203 + j*(-68) -111 + j*(140) --63 + j*(68) --82 + j*(-229) --157 + j*(-313) --190 + j*(279) --104 + j*(61) --180 + j*(-204) -265 + j*(-153) --42 + j*(-48) -100 + j*(172) --147 + j*(-308) -267 + j*(54) --112 + j*(272) --264 + j*(-36) -29 + j*(-332) -140 + j*(-86) -400 + j*(-38) --121 + j*(-231) --42 + j*(344) -129 + j*(-81) --111 + j*(226) -3 + j*(150) --37 + j*(18) -0 + j*(-82) -153 + j*(151) -81 + j*(91) --136 + j*(184) -503 + j*(-113) --49 + j*(319) -70 + j*(77) -197 + j*(-66) --62 + j*(149) -254 + j*(-122) -45 + j*(-32) -3 + j*(9) -25 + j*(89) -6 + j*(-45) --22 + j*(161) --40 + j*(83) -103 + j*(23) -110 + j*(278) -8 + j*(-61) --57 + j*(37) --99 + j*(86) --64 + j*(339) --37 + j*(214) --84 + j*(6) -303 + j*(-178) -205 + j*(97) -11 + j*(194) -129 + j*(11) -687 + j*(-100) -187 + j*(-238) -40 + j*(-74) -332 + j*(-25) --94 + j*(165) -64 + j*(246) --291 + j*(-108) --121 + j*(-284) -216 + j*(-104) -159 + j*(23) -75 + j*(-47) -70 + j*(4) --10 + j*(-34) --155 + j*(34) --35 + j*(89) --13 + j*(-134) --99 + j*(40) --463 + j*(-13) --252 + j*(172) --22 + j*(-351) --69 + j*(88) --284 + j*(-21) -13 + j*(-6) --35 + j*(-71) --40 + j*(317) -405 + j*(-60) --358 + j*(104) -56 + j*(-119) --135 + j*(-156) --66 + j*(-23) -168 + j*(59) -148 + j*(-76) --213 + j*(-190) --190 + j*(-27) -103 + j*(392) -52 + j*(110) -211 + j*(-61) --165 + j*(218) -3 + j*(-231) -69 + j*(-161) --263 + j*(54) -98 + j*(-191) -30 + j*(167) -45 + j*(9) --373 + j*(181) -69 + j*(105) --23 + j*(-100) --127 + j*(-9) --64 + j*(287) -202 + j*(290) -115 + j*(-109) --72 + j*(-205) -166 + j*(238) -151 + j*(-25) -186 + j*(290) --108 + j*(33) --163 + j*(-180) -148 + j*(124) -94 + j*(-270) --52 + j*(27) -161 + j*(134) --61 + j*(-25) --23 + j*(-233) -93 + j*(-245) -57 + j*(162) --172 + j*(-354) -133 + j*(129) -339 + j*(107) -12 + j*(65) -6 + j*(-80) --51 + j*(-17) --13 + j*(-37) --18 + j*(-258) --54 + j*(-141) -295 + j*(6) --215 + j*(-192) --109 + j*(-73) -105 + j*(43) --277 + j*(-251) -57 + j*(188) --38 + j*(390) --117 + j*(-390) -107 + j*(233) -131 + j*(98) -366 + j*(-215) --136 + j*(-154) -45 + j*(-112) --10 + j*(-6) -27 + j*(-114) --119 + j*(8) --163 + j*(-4) -78 + j*(261) -221 + j*(-37) --92 + j*(-23) -4 + j*(221) --2 + j*(-153) --76 + j*(-158) -66 + j*(141) --182 + j*(136) --446 + j*(-88) -71 + j*(-145) --75 + j*(-87) -101 + j*(-97) --177 + j*(146) -93 + j*(21) -324 + j*(397) -281 + j*(-229) --138 + j*(117) --188 + j*(112) -39 + j*(-66) -163 + j*(-98) -71 + j*(57) --65 + j*(187) -125 + j*(197) --135 + j*(141) --105 + j*(47) -19 + j*(-86) -66 + j*(-235) --480 + j*(225) -76 + j*(28) -342 + j*(47) -0 + j*(-366) --140 + j*(74) -193 + j*(144) --126 + j*(-43) --191 + j*(158) --180 + j*(-55) -63 + j*(-255) --98 + j*(-2) --13 + j*(308) --183 + j*(207) -144 + j*(37) --51 + j*(-175) -28 + j*(-29) --211 + j*(356) --132 + j*(173) --173 + j*(199) -36 + j*(329) --139 + j*(228) --311 + j*(177) -65 + j*(-343) --217 + j*(-20) -119 + j*(18) -29 + j*(-58) -156 + j*(129) --41 + j*(23) -202 + j*(-163) -224 + j*(196) --47 + j*(25) -15 + j*(-122) --182 + j*(280) --170 + j*(21) -8 + j*(-144) -20 + j*(246) --148 + j*(143) -91 + j*(93) -168 + j*(44) --100 + j*(270) --51 + j*(-167) --285 + j*(125) --93 + j*(63) --1 + j*(-290) --214 + j*(-47) --78 + j*(243) --156 + j*(-314) -152 + j*(57) -163 + j*(267) -8 + j*(-167) --262 + j*(114) -132 + j*(49) -199 + j*(-85) -3 + j*(228) -57 + j*(-151) -104 + j*(-98) --45 + j*(-381) -238 + j*(-59) --62 + j*(-158) --96 + j*(-87) -8 + j*(279) --84 + j*(260) -276 + j*(127) --142 + j*(-42) --119 + j*(-185) -67 + j*(134) --20 + j*(129) --47 + j*(-30) --250 + j*(156) -200 + j*(108) --450 + j*(49) --30 + j*(87) -205 + j*(-137) --165 + j*(217) -100 + j*(-165) --52 + j*(-71) --232 + j*(-131) --289 + j*(-36) -310 + j*(-194) --88 + j*(127) -17 + j*(-71) -50 + j*(232) -181 + j*(21) --65 + j*(-333) -158 + j*(-238) -176 + j*(-210) --279 + j*(173) --21 + j*(-192) --363 + j*(-361) -6 + j*(185) --25 + j*(-4) -62 + j*(-21) -33 + j*(-59) -2 + j*(-121) --192 + j*(-84) -32 + j*(204) -23 + j*(57) --186 + j*(341) -1 + j*(-191) --262 + j*(-313) -121 + j*(13) --211 + j*(-185) --470 + j*(23) --221 + j*(94) -50 + j*(25) --277 + j*(53) -174 + j*(29) --26 + j*(-297) --1 + j*(-285) -90 + j*(-249) -50 + j*(214) -72 + j*(-9) --107 + j*(-288) --98 + j*(-368) --146 + j*(-28) --135 + j*(-53) --245 + j*(240) --88 + j*(134) -211 + j*(-91) --175 + j*(42) -117 + j*(212) -179 + j*(-4) --96 + j*(202) --119 + j*(-134) -22 + j*(291) --515 + j*(119) -36 + j*(-319) -190 + j*(-428) -128 + j*(-48) -458 + j*(-10) --104 + j*(-23) --51 + j*(173) -93 + j*(95) --222 + j*(47) --141 + j*(-39) --175 + j*(-116) -35 + j*(-10) -56 + j*(-146) -275 + j*(14) -14 + j*(31) --105 + j*(-30) -105 + j*(64) -21 + j*(-163) --33 + j*(-29) --56 + j*(-397) --235 + j*(-142) --91 + j*(-166) --112 + j*(-132) -342 + j*(116) -76 + j*(-300) --118 + j*(71) --137 + j*(196) -83 + j*(204) -89 + j*(-214) -78 + j*(-142) --82 + j*(-71) --301 + j*(-57) -141 + j*(111) --74 + j*(4) --76 + j*(179) --545 + j*(209) -121 + j*(-37) -303 + j*(121) --182 + j*(47) -83 + j*(-137) -251 + j*(118) -60 + j*(36) -134 + j*(221) -257 + j*(245) -30 + j*(-115) -192 + j*(-68) --280 + j*(-52) --197 + j*(255) --106 + j*(23) --2 + j*(-309) -175 + j*(305) -78 + j*(31) -86 + j*(-110) --37 + j*(-164) --28 + j*(135) -29 + j*(-107) -161 + j*(228) -269 + j*(167) --46 + j*(-32) --175 + j*(-12) -244 + j*(-436) --118 + j*(276) --151 + j*(-311) --127 + j*(91) -27 + j*(182) -71 + j*(-19) -170 + j*(-5) --67 + j*(75) -196 + j*(233) -253 + j*(47) --23 + j*(-124) -10 + j*(-184) --90 + j*(-4) --13 + j*(-43) --248 + j*(-177) --4 + j*(-153) -192 + j*(-52) --232 + j*(-206) -238 + j*(138) --165 + j*(55) --158 + j*(-70) -77 + j*(55) --6 + j*(47) -227 + j*(-101) -7 + j*(281) --52 + j*(156) -137 + j*(-203) -56 + j*(64) -71 + j*(16) --171 + j*(-17) --127 + j*(325) -8 + j*(91) --107 + j*(197) --25 + j*(22) --203 + j*(-243) -120 + j*(57) -205 + j*(-311) -117 + j*(30) --167 + j*(149) -202 + j*(27) --257 + j*(177) --293 + j*(76) --211 + j*(-262) --106 + j*(-71) --43 + j*(-121) --140 + j*(-146) --118 + j*(138) -114 + j*(-126) -114 + j*(35) --208 + j*(59) -177 + j*(34) --18 + j*(-115) -60 + j*(9) --24 + j*(-62) -288 + j*(66) --176 + j*(-223) -94 + j*(69) -334 + j*(-168) -281 + j*(-23) --40 + j*(139) --59 + j*(-4) --45 + j*(-16) -100 + j*(-16) -216 + j*(-39) -30 + j*(-128) --351 + j*(161) -67 + j*(-194) --213 + j*(-55) -102 + j*(-107) -236 + j*(-30) -317 + j*(-180) -66 + j*(-140) --4 + j*(157) --191 + j*(-49) --101 + j*(-248) --21 + j*(-175) --9 + j*(-108) --268 + j*(-51) -158 + j*(168) -11 + j*(117) --4 + j*(78) -77 + j*(186) -72 + j*(-84) --88 + j*(-228) --66 + j*(-83) --272 + j*(-322) --123 + j*(-65) --105 + j*(25) -368 + j*(-404) -0 + j*(-161) -162 + j*(-31) -96 + j*(232) -236 + j*(-275) -40 + j*(-96) -250 + j*(-218) --234 + j*(-142) --10 + j*(63) --264 + j*(210) -40 + j*(-186) --290 + j*(4) -176 + j*(-90) -109 + j*(282) -13 + j*(465) -40 + j*(7) -129 + j*(-70) --30 + j*(7) --151 + j*(71) --240 + j*(152) --238 + j*(-159) -50 + j*(-19) --81 + j*(76) -132 + j*(-339) -7 + j*(190) -68 + j*(-272) --231 + j*(199) --6 + j*(-153) --71 + j*(224) --362 + j*(203) -122 + j*(-11) -125 + j*(-11) -40 + j*(-13) -69 + j*(370) -128 + j*(-18) --73 + j*(77) --194 + j*(-13) -144 + j*(33) -168 + j*(331) --224 + j*(-53) -18 + j*(-140) --47 + j*(232) -20 + j*(-175) -235 + j*(-91) -241 + j*(-113) --290 + j*(-156) --180 + j*(-276) --187 + j*(69) --25 + j*(-264) --29 + j*(-21) --70 + j*(-210) --301 + j*(-95) --34 + j*(-162) --252 + j*(10) -80 + j*(-33) --62 + j*(-161) -14 + j*(29) -83 + j*(170) -154 + j*(-146) -50 + j*(-245) -112 + j*(82) --60 + j*(132) -257 + j*(174) --10 + j*(-168) -147 + j*(-98) --224 + j*(-255) --240 + j*(-171) -155 + j*(-137) --81 + j*(138) --325 + j*(-52) -247 + j*(141) --365 + j*(16) -385 + j*(-28) -165 + j*(-25) --62 + j*(60) --140 + j*(-218) -426 + j*(178) --83 + j*(156) -163 + j*(-32) -263 + j*(13) --159 + j*(45) --7 + j*(-478) --43 + j*(221) -37 + j*(-121) -57 + j*(-92) -4 + j*(207) --91 + j*(-10) --173 + j*(31) -182 + j*(-86) -153 + j*(59) --259 + j*(-192) -185 + j*(-95) -155 + j*(169) -136 + j*(-41) --330 + j*(-250) --178 + j*(-422) -218 + j*(307) -264 + j*(-365) -317 + j*(-4) -424 + j*(-73) --162 + j*(-162) --238 + j*(-79) --28 + j*(270) --309 + j*(224) -230 + j*(42) -168 + j*(66) -243 + j*(-93) --57 + j*(248) --28 + j*(131) --1 + j*(173) --61 + j*(-118) --35 + j*(104) -156 + j*(-25) -20 + j*(182) --57 + j*(-141) --115 + j*(-38) -68 + j*(-209) -97 + j*(-191) -170 + j*(226) -70 + j*(42) --115 + j*(105) --105 + j*(167) --153 + j*(-176) -1 + j*(214) -144 + j*(404) -76 + j*(303) -220 + j*(2) --428 + j*(-21) --53 + j*(49) --35 + j*(262) -29 + j*(-51) -104 + j*(-71) -161 + j*(-219) -57 + j*(-207) --167 + j*(200) --170 + j*(174) --46 + j*(-60) -4 + j*(-160) -117 + j*(50) -390 + j*(21) --37 + j*(16) -3 + j*(-183) --27 + j*(194) -93 + j*(42) --457 + j*(214) -310 + j*(-107) --8 + j*(-76) -282 + j*(183) --30 + j*(56) -201 + j*(322) -421 + j*(227) -230 + j*(-49) -156 + j*(-142) --208 + j*(-272) --81 + j*(-156) --293 + j*(-89) --108 + j*(-82) -225 + j*(73) --69 + j*(91) --227 + j*(-105) -350 + j*(-50) -8 + j*(-212) --149 + j*(234) --61 + j*(139) -134 + j*(-105) -177 + j*(-169) --113 + j*(113) -178 + j*(44) -120 + j*(62) --1 + j*(253) --45 + j*(-24) -240 + j*(-194) -23 + j*(90) -237 + j*(68) --13 + j*(83) --148 + j*(-37) -136 + j*(-278) --175 + j*(334) -160 + j*(-148) -153 + j*(-133) -60 + j*(124) --221 + j*(-114) -96 + j*(116) --43 + j*(30) -38 + j*(-186) --302 + j*(-27) -93 + j*(-78) --64 + j*(274) --75 + j*(-1) -66 + j*(232) -199 + j*(22) --64 + j*(40) --199 + j*(66) -168 + j*(-209) -122 + j*(-142) -305 + j*(71) --11 + j*(-146) --418 + j*(5) -24 + j*(133) -203 + j*(-218) -394 + j*(165) --156 + j*(-112) -93 + j*(-129) --204 + j*(59) -95 + j*(317) --151 + j*(-274) --122 + j*(-175) --115 + j*(-29) --50 + j*(-112) -224 + j*(-140) -47 + j*(-1) --80 + j*(-177) --244 + j*(-238) --102 + j*(45) --117 + j*(-63) -62 + j*(8) --85 + j*(20) --209 + j*(-100) --118 + j*(-187) --158 + j*(57) --174 + j*(-190) --23 + j*(389) --24 + j*(110) --163 + j*(-100) -45 + j*(234) --49 + j*(76) --349 + j*(193) --40 + j*(-93) -162 + j*(120) --119 + j*(-11) --126 + j*(322) -42 + j*(240) -49 + j*(-10) -445 + j*(175) --243 + j*(78) -95 + j*(-86) -237 + j*(66) -148 + j*(-190) --105 + j*(37) -112 + j*(40) --134 + j*(-176) -241 + j*(-241) --398 + j*(185) --57 + j*(36) -323 + j*(36) -206 + j*(-162) --100 + j*(231) --121 + j*(192) -52 + j*(68) -113 + j*(-16) --312 + j*(-42) -185 + j*(-37) --140 + j*(124) -252 + j*(-82) -74 + j*(-66) --182 + j*(-21) --168 + j*(-48) --198 + j*(-36) --100 + j*(-97) -108 + j*(-23) -16 + j*(-69) --303 + j*(-143) --182 + j*(-119) -149 + j*(-485) -279 + j*(110) --151 + j*(-129) -263 + j*(-245) -166 + j*(28) -216 + j*(74) -25 + j*(96) --122 + j*(146) -81 + j*(103) -129 + j*(-6) --167 + j*(-17) --351 + j*(-259) -3 + j*(-125) --163 + j*(68) -279 + j*(91) --49 + j*(-257) -195 + j*(-93) -47 + j*(118) --197 + j*(-392) --125 + j*(-238) -284 + j*(48) -218 + j*(-397) -72 + j*(-14) --46 + j*(223) --140 + j*(-227) -182 + j*(-205) --218 + j*(-226) --57 + j*(-305) --48 + j*(-37) --199 + j*(-303) -16 + j*(-168) -38 + j*(-11) --73 + j*(-53) --142 + j*(-253) --83 + j*(246) -77 + j*(-91) --128 + j*(-83) --315 + j*(-84) --229 + j*(-173) --238 + j*(-5) -118 + j*(-53) --119 + j*(124) -57 + j*(-78) -33 + j*(-105) --52 + j*(-35) --11 + j*(87) --172 + j*(18) --40 + j*(-88) --42 + j*(188) -3 + j*(-257) --205 + j*(97) -244 + j*(337) --30 + j*(35) -52 + j*(-91) --379 + j*(-11) --187 + j*(-46) --99 + j*(-209) --197 + j*(-16) --168 + j*(-129) --429 + j*(34) --54 + j*(-23) --110 + j*(-78) -328 + j*(98) --142 + j*(139) --204 + j*(124) --123 + j*(-131) --110 + j*(-260) -47 + j*(-187) -138 + j*(121) --160 + j*(91) --414 + j*(-91) --73 + j*(169) --91 + j*(-195) --343 + j*(-139) --105 + j*(-62) -127 + j*(308) -43 + j*(147) --381 + j*(40) --107 + j*(197) -264 + j*(-93) --170 + j*(122) -156 + j*(-71) --37 + j*(233) -77 + j*(51) -152 + j*(14) --35 + j*(76) --259 + j*(124) --253 + j*(10) -234 + j*(-71) -562 + j*(-276) -0 + j*(88) -45 + j*(115) --56 + j*(-43) -262 + j*(25) --69 + j*(119) --143 + j*(-172) -176 + j*(-386) --144 + j*(38) --18 + j*(170) -259 + j*(-262) --8 + j*(88) --113 + j*(-90) -139 + j*(74) -141 + j*(-67) -208 + j*(-146) -118 + j*(46) --156 + j*(-5) --69 + j*(-154) --252 + j*(115) -93 + j*(6) -55 + j*(257) -19 + j*(62) -211 + j*(129) --421 + j*(107) -120 + j*(77) --86 + j*(-219) --292 + j*(-37) --13 + j*(-209) --185 + j*(-60) --71 + j*(163) --301 + j*(-11) --138 + j*(188) -110 + j*(6) -310 + j*(356) -101 + j*(-104) --11 + j*(125) -107 + j*(81) -157 + j*(-269) --98 + j*(-77) -427 + j*(-223) --159 + j*(154) -11 + j*(148) --168 + j*(-61) -19 + j*(-80) --69 + j*(276) --376 + j*(283) -23 + j*(91) --237 + j*(41) --194 + j*(11) --209 + j*(-356) --21 + j*(170) --204 + j*(92) -180 + j*(89) --72 + j*(52) --102 + j*(128) -155 + j*(-105) --308 + j*(215) --206 + j*(187) --31 + j*(27) --264 + j*(33) -192 + j*(50) --184 + j*(-98) --213 + j*(-190) --296 + j*(-141) -42 + j*(-74) -59 + j*(153) --2 + j*(-122) -124 + j*(-98) -37 + j*(-61) --5 + j*(-226) --327 + j*(-73) -187 + j*(238) --193 + j*(145) --49 + j*(199) -12 + j*(-103) -254 + j*(-51) -138 + j*(-86) -166 + j*(-317) -61 + j*(-37) --264 + j*(37) --108 + j*(-327) --274 + j*(312) --293 + j*(146) --120 + j*(-36) -153 + j*(-57) -91 + j*(205) --26 + j*(432) --310 + j*(168) -137 + j*(171) --57 + j*(11) -233 + j*(-103) --19 + j*(-187) --33 + j*(-207) --239 + j*(153) -250 + j*(-412) -23 + j*(-238) -218 + j*(-332) -284 + j*(-149) -68 + j*(37) --3 + j*(303) -145 + j*(90) -7 + j*(-6) -93 + j*(-117) -218 + j*(-139) --204 + j*(30) --51 + j*(-193) --52 + j*(-139) --104 + j*(-123) --164 + j*(55) -169 + j*(12) --155 + j*(-104) -230 + j*(26) --1 + j*(93) --243 + j*(-438) --313 + j*(98) -22 + j*(-40) --18 + j*(166) -116 + j*(-16) --221 + j*(156) -10 + j*(-282) --21 + j*(41) --111 + j*(-107) -78 + j*(68) --165 + j*(14) --99 + j*(16) -315 + j*(66) -11 + j*(-98) -65 + j*(97) --82 + j*(227) -35 + j*(-300) --29 + j*(30) -222 + j*(-175) -89 + j*(91) -133 + j*(-55) --165 + j*(26) -294 + j*(-19) --134 + j*(173) --6 + j*(-123) -265 + j*(316) --37 + j*(-37) -37 + j*(-9) --28 + j*(54) -66 + j*(52) --2 + j*(-216) -111 + j*(-18) -144 + j*(153) -46 + j*(17) --18 + j*(184) --277 + j*(-111) -136 + j*(-34) -181 + j*(-19) --358 + j*(42) -112 + j*(24) --58 + j*(-71) -21 + j*(89) -250 + j*(2) --151 + j*(7) --45 + j*(29) --100 + j*(-1) --96 + j*(148) -197 + j*(52) --18 + j*(-540) -7 + j*(-98) --18 + j*(27) -74 + j*(166) --16 + j*(-130) -62 + j*(108) -37 + j*(88) --97 + j*(-153) --11 + j*(36) --204 + j*(48) -70 + j*(115) --161 + j*(142) --72 + j*(-76) -156 + j*(112) -149 + j*(317) --163 + j*(193) -353 + j*(-178) -160 + j*(-74) -67 + j*(201) --218 + j*(146) -111 + j*(42) --27 + j*(28) --207 + j*(-126) -115 + j*(68) -178 + j*(95) -110 + j*(-12) -74 + j*(-181) --38 + j*(-50) -147 + j*(321) -132 + j*(110) -297 + j*(158) --107 + j*(59) -100 + j*(142) --35 + j*(252) -122 + j*(69) -105 + j*(-229) -34 + j*(-2) -479 + j*(-9) --16 + j*(96) -201 + j*(-258) --104 + j*(133) -129 + j*(-23) -194 + j*(134) --106 + j*(-35) --281 + j*(-300) -36 + j*(-212) --175 + j*(21) --287 + j*(86) -79 + j*(-139) -173 + j*(133) -16 + j*(-117) --152 + j*(33) -201 + j*(-59) --149 + j*(150) --75 + j*(-175) --416 + j*(-181) --64 + j*(-284) -0 + j*(401) --170 + j*(425) --214 + j*(-47) --211 + j*(247) --98 + j*(8) --129 + j*(447) -271 + j*(272) -9 + j*(-279) --64 + j*(-25) -176 + j*(240) --462 + j*(-388) --25 + j*(391) -132 + j*(-235) -173 + j*(-240) -371 + j*(-346) -230 + j*(-164) --228 + j*(18) --81 + j*(323) -150 + j*(89) -197 + j*(-226) -387 + j*(-117) -170 + j*(-281) --300 + j*(-19) --4 + j*(-175) -428 + j*(-17) -523 + j*(419) -168 + j*(455) --202 + j*(-57) --372 + j*(-344) --133 + j*(-50) -87 + j*(-18) --21 + j*(347) -237 + j*(446) --267 + j*(-60) --407 + j*(-203) --99 + j*(-204) -259 + j*(247) --342 + j*(342) -273 + j*(330) --400 + j*(238) -365 + j*(-625) -400 + j*(-322) -5 + j*(168) -371 + j*(329) -148 + j*(443) -134 + j*(-100) --497 + j*(272) --395 + j*(400) --403 + j*(267) -411 + j*(-407) --341 + j*(-416) -155 + j*(-460) -332 + j*(-323) --194 + j*(42) --268 + j*(133) -224 + j*(-124) -535 + j*(478) -143 + j*(-390) -368 + j*(-152) --110 + j*(-284) --693 + j*(-241) --386 + j*(450) --215 + j*(373) --156 + j*(189) -349 + j*(-105) -390 + j*(61) -269 + j*(-430) -183 + j*(-207) --150 + j*(-489) -518 + j*(531) -186 + j*(692) -395 + j*(-305) -166 + j*(249) -243 + j*(-417) --135 + j*(-226) -103 + j*(46) -281 + j*(125) -182 + j*(351) --250 + j*(40) --157 + j*(-467) --240 + j*(178) -170 + j*(-20) --379 + j*(-303) --149 + j*(295) -444 + j*(-149) -595 + j*(231) --92 + j*(-199) --362 + j*(-141) --561 + j*(33) -588 + j*(-375) --267 + j*(-479) -327 + j*(100) --598 + j*(-174) --42 + j*(406) -342 + j*(-147) -336 + j*(-131) -140 + j*(115) -438 + j*(119) --50 + j*(100) -277 + j*(402) --230 + j*(-449) -202 + j*(367) -388 + j*(-771) -288 + j*(-619) -204 + j*(-395) --47 + j*(-322) --293 + j*(322) --315 + j*(-171) --141 + j*(127) --414 + j*(-54) -36 + j*(366) --325 + j*(466) -471 + j*(-397) --284 + j*(-148) --380 + j*(111) -277 + j*(-126) -252 + j*(220) -81 + j*(-233) -241 + j*(-114) --260 + j*(417) -462 + j*(-177) --95 + j*(398) --182 + j*(-351) --76 + j*(-392) --268 + j*(-288) -351 + j*(-228) -501 + j*(62) -51 + j*(273) --418 + j*(-262) -385 + j*(198) --156 + j*(497) -185 + j*(-89) --111 + j*(-339) --297 + j*(260) -141 + j*(-395) -202 + j*(-265) -291 + j*(-190) -344 + j*(83) --349 + j*(64) --132 + j*(284) -361 + j*(363) -212 + j*(241) -527 + j*(514) -69 + j*(530) -403 + j*(281) --375 + j*(-121) --355 + j*(-482) -177 + j*(158) -187 + j*(-8) -696 + j*(-346) -132 + j*(-311) -1 + j*(213) -395 + j*(-237) -303 + j*(246) -320 + j*(-262) -308 + j*(187) -527 + j*(18) --641 + j*(192) --265 + j*(-494) -703 + j*(446) -412 + j*(116) --544 + j*(392) -219 + j*(387) --129 + j*(351) --192 + j*(187) --379 + j*(-465) -322 + j*(-293) -192 + j*(-500) -22 + j*(351) --387 + j*(-301) --67 + j*(456) -194 + j*(450) -218 + j*(-581) --276 + j*(-107) -187 + j*(198) -28 + j*(-418) --85 + j*(292) --156 + j*(-344) --214 + j*(-260) --151 + j*(-267) -41 + j*(-289) -347 + j*(329) --33 + j*(-435) -76 + j*(298) -202 + j*(222) --78 + j*(284) -575 + j*(-494) -291 + j*(204) -197 + j*(523) --494 + j*(-342) -86 + j*(328) -257 + j*(600) -236 + j*(-177) --128 + j*(-152) --214 + j*(-280) -251 + j*(352) --202 + j*(17) -74 + j*(424) --280 + j*(276) --160 + j*(293) -337 + j*(310) --448 + j*(-120) --243 + j*(-566) --279 + j*(-2) -298 + j*(483) --263 + j*(459) --253 + j*(-158) --312 + j*(-397) --192 + j*(228) --249 + j*(-423) -51 + j*(-308) -526 + j*(-261) -74 + j*(446) --124 + j*(-276) --95 + j*(444) -16 + j*(163) --301 + j*(110) -457 + j*(-303) --216 + j*(-169) -429 + j*(-260) --603 + j*(436) -57 + j*(324) --115 + j*(-294) -313 + j*(295) -470 + j*(-225) -518 + j*(129) --504 + j*(-204) --540 + j*(-33) --177 + j*(-329) -253 + j*(-247) --467 + j*(-372) -185 + j*(-238) -267 + j*(186) --384 + j*(141) -250 + j*(-291) --3 + j*(-309) --214 + j*(-30) -118 + j*(635) --256 + j*(327) -312 + j*(-137) -197 + j*(-70) -18 + j*(-503) -317 + j*(367) -181 + j*(-424) --344 + j*(-240) -57 + j*(-547) --364 + j*(13) --27 + j*(-107) --59 + j*(80) -369 + j*(51) --217 + j*(-81) --407 + j*(509) -291 + j*(182) --293 + j*(334) -28 + j*(-156) --438 + j*(400) -343 + j*(-96) -477 + j*(371) --287 + j*(-291) -482 + j*(328) --282 + j*(-414) -61 + j*(179) --224 + j*(-69) --153 + j*(331) -188 + j*(-46) -41 + j*(-78) --571 + j*(556) --293 + j*(91) --260 + j*(90) -239 + j*(-81) --174 + j*(-201) -262 + j*(189) --197 + j*(-334) -368 + j*(311) --501 + j*(88) --48 + j*(-481) -325 + j*(389) --238 + j*(86) --356 + j*(-254) --293 + j*(-133) -287 + j*(380) -527 + j*(33) -497 + j*(-288) -432 + j*(-242) -409 + j*(-207) -28 + j*(-156) --240 + j*(181) --320 + j*(-711) --104 + j*(-373) -341 + j*(-32) --406 + j*(-363) -155 + j*(57) --262 + j*(190) -210 + j*(742) -65 + j*(-220) --291 + j*(-206) --197 + j*(352) --100 + j*(-406) -356 + j*(320) --412 + j*(217) --3 + j*(602) -382 + j*(-284) --122 + j*(93) --682 + j*(-298) -276 + j*(62) --551 + j*(75) -607 + j*(474) -26 + j*(235) -252 + j*(-453) --262 + j*(-438) --40 + j*(-168) --53 + j*(71) -192 + j*(431) -435 + j*(-244) -380 + j*(358) --403 + j*(-416) --105 + j*(-338) -58 + j*(-154) --199 + j*(-422) --193 + j*(391) -281 + j*(-103) -298 + j*(-147) -426 + j*(-414) -398 + j*(100) -165 + j*(140) -126 + j*(-89) -122 + j*(300) --155 + j*(-434) --440 + j*(69) -391 + j*(-152) --307 + j*(-64) -285 + j*(-441) --154 + j*(-491) --419 + j*(-529) --31 + j*(-330) -60 + j*(81) --173 + j*(132) -488 + j*(338) --42 + j*(-450) --159 + j*(-192) --74 + j*(-560) -235 + j*(-305) --415 + j*(-184) --165 + j*(-223) -158 + j*(383) -27 + j*(-197) --255 + j*(-47) -438 + j*(315) -138 + j*(-294) --40 + j*(-127) -337 + j*(-310) -257 + j*(239) -25 + j*(385) --507 + j*(55) --337 + j*(185) -355 + j*(501) --223 + j*(258) -161 + j*(-298) --408 + j*(-71) --342 + j*(351) -256 + j*(-382) --455 + j*(194) --324 + j*(457) --124 + j*(509) --184 + j*(209) -51 + j*(-226) --337 + j*(-282) --38 + j*(-43) -95 + j*(110) -163 + j*(-158) --318 + j*(-346) -160 + j*(321) --257 + j*(310) -305 + j*(-486) -258 + j*(214) --281 + j*(-214) -293 + j*(9) --225 + j*(-240) -207 + j*(-445) --308 + j*(185) --59 + j*(-70) --493 + j*(-380) -655 + j*(-197) --268 + j*(-100) -315 + j*(-30) -382 + j*(-180) -45 + j*(-370) -396 + j*(391) --488 + j*(-400) --333 + j*(-64) --162 + j*(456) --315 + j*(-665) -229 + j*(205) --97 + j*(441) -278 + j*(227) --42 + j*(-278) --182 + j*(413) -286 + j*(69) --286 + j*(530) -86 + j*(326) -196 + j*(257) --218 + j*(161) -444 + j*(-151) --243 + j*(11) --325 + j*(329) -648 + j*(55) -546 + j*(632) --120 + j*(370) -127 + j*(-274) -341 + j*(356) -605 + j*(-571) -129 + j*(441) --491 + j*(-367) -427 + j*(-232) --573 + j*(33) -99 + j*(240) --359 + j*(-138) -229 + j*(165) -309 + j*(119) -242 + j*(284) --192 + j*(27) -621 + j*(-439) --198 + j*(181) --245 + j*(275) --130 + j*(-330) -286 + j*(187) -295 + j*(-190) -665 + j*(218) -266 + j*(-188) --49 + j*(-291) --264 + j*(-29) -156 + j*(-284) -106 + j*(200) -342 + j*(250) -456 + j*(8) --72 + j*(-268) -132 + j*(385) -190 + j*(-104) -125 + j*(-565) -233 + j*(103) -260 + j*(9) -6 + j*(-413) -358 + j*(-296) --222 + j*(-221) --90 + j*(335) -361 + j*(-165) -440 + j*(344) --477 + j*(81) --384 + j*(-272) -366 + j*(144) -482 + j*(268) -368 + j*(-361) -270 + j*(-76) -238 + j*(-549) --412 + j*(-489) --165 + j*(28) --234 + j*(303) -53 + j*(263) --335 + j*(463) -435 + j*(-43) -402 + j*(-403) -573 + j*(438) --498 + j*(-515) --197 + j*(243) -456 + j*(28) --546 + j*(409) --193 + j*(-208) -66 + j*(417) --84 + j*(330) --218 + j*(-150) -378 + j*(202) -177 + j*(-46) -472 + j*(106) --259 + j*(-188) -291 + j*(-82) -251 + j*(423) -187 + j*(-513) -385 + j*(206) --281 + j*(-349) -105 + j*(202) --230 + j*(448) --470 + j*(-348) -13 + j*(-522) --318 + j*(-141) --642 + j*(-298) -82 + j*(-451) --448 + j*(419) -349 + j*(435) --437 + j*(618) --74 + j*(-261) -207 + j*(-99) --386 + j*(292) -290 + j*(-264) -431 + j*(-342) -346 + j*(-221) -240 + j*(151) --209 + j*(-525) --188 + j*(-429) --590 + j*(-514) -409 + j*(-223) --315 + j*(285) --521 + j*(-451) -202 + j*(458) --221 + j*(-139) -236 + j*(378) --672 + j*(421) -1 + j*(315) --83 + j*(-494) --306 + j*(396) -185 + j*(-515) --528 + j*(120) --441 + j*(96) --17 + j*(-30) -213 + j*(271) -631 + j*(-5) -364 + j*(26) -289 + j*(-235) --78 + j*(269) --317 + j*(-59) --365 + j*(-119) --433 + j*(439) -524 + j*(208) --506 + j*(479) -144 + j*(-102) -218 + j*(486) -166 + j*(308) -340 + j*(-202) -195 + j*(376) --243 + j*(18) -666 + j*(-218) --438 + j*(-264) --342 + j*(328) --4 + j*(-325) -266 + j*(344) --282 + j*(80) --177 + j*(581) --470 + j*(-49) -173 + j*(-510) --232 + j*(204) -192 + j*(-291) --95 + j*(-459) --422 + j*(420) --381 + j*(442) --5 + j*(-301) -23 + j*(-64) --246 + j*(-320) -86 + j*(22) -227 + j*(153) -523 + j*(-78) --17 + j*(234) -152 + j*(221) -361 + j*(127) -477 + j*(-136) --260 + j*(-223) --452 + j*(-424) --38 + j*(316) -7 + j*(41) -314 + j*(-93) --199 + j*(-49) -373 + j*(27) -138 + j*(-133) -670 + j*(440) -279 + j*(-281) -651 + j*(-272) --327 + j*(352) --197 + j*(-193) -50 + j*(-195) --464 + j*(169) -91 + j*(299) --268 + j*(-354) --175 + j*(243) -209 + j*(-299) -246 + j*(-74) --211 + j*(32) --590 + j*(-237) --349 + j*(-13) -493 + j*(91) -163 + j*(-473) --229 + j*(-415) -341 + j*(-74) --523 + j*(-462) -233 + j*(354) -476 + j*(-384) --311 + j*(429) --110 + j*(129) -316 + j*(-384) --472 + j*(187) -276 + j*(-151) --118 + j*(-93) -290 + j*(212) -427 + j*(168) --263 + j*(495) -173 + j*(170) --376 + j*(113) --264 + j*(252) --285 + j*(-351) -477 + j*(-281) --305 + j*(39) --271 + j*(75) --76 + j*(113) --59 + j*(45) -64 + j*(-188) -131 + j*(244) -23 + j*(242) -6 + j*(-276) -34 + j*(-119) --132 + j*(123) -158 + j*(-139) --154 + j*(-136) --228 + j*(-295) --5 + j*(-81) --198 + j*(-13) --163 + j*(-329) -123 + j*(-270) --20 + j*(-197) --28 + j*(-51) -145 + j*(-162) -157 + j*(24) --126 + j*(54) -371 + j*(-254) --260 + j*(-204) --182 + j*(-146) -156 + j*(264) -168 + j*(-101) -11 + j*(-81) --284 + j*(-288) --79 + j*(-81) -76 + j*(137) --160 + j*(-287) -165 + j*(-95) -83 + j*(7) -83 + j*(-138) --11 + j*(134) --58 + j*(281) -11 + j*(-214) --231 + j*(-128) -124 + j*(-11) --13 + j*(-123) --122 + j*(154) -286 + j*(-387) --153 + j*(59) --168 + j*(-157) --93 + j*(204) -143 + j*(237) -164 + j*(47) --13 + j*(170) --236 + j*(-96) -57 + j*(395) -71 + j*(-207) --18 + j*(-145) --165 + j*(-25) --185 + j*(-54) -144 + j*(6) --3 + j*(202) --39 + j*(137) -75 + j*(64) -65 + j*(-144) -57 + j*(-88) -130 + j*(-175) -86 + j*(268) --220 + j*(99) --303 + j*(-27) --86 + j*(-230) -0 + j*(-168) --86 + j*(-19) --112 + j*(-159) --46 + j*(-31) --248 + j*(334) -47 + j*(23) -109 + j*(130) --86 + j*(-11) -48 + j*(-79) --115 + j*(35) --107 + j*(139) --181 + j*(244) -33 + j*(-192) -72 + j*(235) -13 + j*(-37) --188 + j*(-218) --122 + j*(139) -83 + j*(211) -11 + j*(-64) --1 + j*(80) -6 + j*(296) --327 + j*(32) -51 + j*(-163) -5 + j*(-147) -89 + j*(-125) -72 + j*(-122) -163 + j*(119) -45 + j*(-27) --14 + j*(194) -67 + j*(35) --115 + j*(138) --69 + j*(352) --124 + j*(264) -358 + j*(-136) -16 + j*(-250) --62 + j*(148) --21 + j*(-112) -100 + j*(-281) --192 + j*(256) --50 + j*(113) -83 + j*(-140) --53 + j*(-184) -26 + j*(226) --146 + j*(-12) -59 + j*(323) -92 + j*(-313) -74 + j*(182) --87 + j*(371) --54 + j*(388) -102 + j*(-137) --317 + j*(235) -113 + j*(-13) --125 + j*(-184) --296 + j*(-134) --24 + j*(-75) -211 + j*(-616) --286 + j*(-27) -153 + j*(129) --287 + j*(221) -139 + j*(-23) -211 + j*(-58) -34 + j*(-3) -68 + j*(58) --232 + j*(52) --57 + j*(-89) -30 + j*(-63) -412 + j*(81) -44 + j*(65) --155 + j*(248) --379 + j*(57) -226 + j*(-62) -40 + j*(-147) -50 + j*(-100) -223 + j*(-29) --38 + j*(-45) --107 + j*(103) --33 + j*(-237) --35 + j*(5) -49 + j*(-75) -230 + j*(-153) -36 + j*(-48) --76 + j*(64) -17 + j*(-260) --31 + j*(134) --52 + j*(-53) --49 + j*(-129) --400 + j*(531) -103 + j*(29) --274 + j*(317) --204 + j*(297) -33 + j*(2) --34 + j*(27) --18 + j*(-21) -118 + j*(49) --165 + j*(-112) -20 + j*(48) -112 + j*(-151) --61 + j*(-64) --165 + j*(-1) --86 + j*(205) --132 + j*(-49) -227 + j*(115) --112 + j*(-151) --229 + j*(208) --18 + j*(288) --11 + j*(-17) --87 + j*(-221) -59 + j*(-103) -178 + j*(34) --68 + j*(78) --331 + j*(236) --50 + j*(202) --406 + j*(300) -168 + j*(360) -66 + j*(135) -210 + j*(-129) -261 + j*(-44) --182 + j*(100) --231 + j*(-123) --11 + j*(49) --225 + j*(-245) -299 + j*(-52) -57 + j*(-13) --121 + j*(342) --224 + j*(191) -13 + j*(-150) --9 + j*(-26) -146 + j*(-146) -192 + j*(-49) --19 + j*(-104) -92 + j*(-254) -214 + j*(-313) --219 + j*(19) --65 + j*(-359) --255 + j*(-38) -65 + j*(177) --96 + j*(-128) --78 + j*(6) -16 + j*(-17) --260 + j*(-66) --95 + j*(-110) -193 + j*(87) -77 + j*(-107) --19 + j*(-52) --70 + j*(-187) -547 + j*(262) --59 + j*(-39) -126 + j*(46) --47 + j*(-180) -18 + j*(-137) -18 + j*(-50) -110 + j*(354) -273 + j*(18) --44 + j*(-349) -97 + j*(-141) -112 + j*(173) -42 + j*(204) --33 + j*(-132) -157 + j*(-131) -62 + j*(-146) -84 + j*(-30) --169 + j*(163) -90 + j*(-85) --211 + j*(215) --147 + j*(-100) --325 + j*(17) -11 + j*(132) --309 + j*(99) --291 + j*(-136) -183 + j*(32) -25 + j*(-317) --243 + j*(-312) -115 + j*(129) --78 + j*(79) -249 + j*(-482) -160 + j*(-260) --12 + j*(130) --395 + j*(1) -330 + j*(-161) -21 + j*(9) --133 + j*(-103) -361 + j*(-362) -222 + j*(204) --265 + j*(88) --35 + j*(197) --187 + j*(123) --22 + j*(101) --37 + j*(12) --42 + j*(-145) -112 + j*(-66) --208 + j*(-199) --221 + j*(181) -2 + j*(-8) --106 + j*(-108) -238 + j*(28) -113 + j*(-265) --43 + j*(-2) --194 + j*(151) -485 + j*(0) --87 + j*(-110) --52 + j*(-28) --11 + j*(144) -63 + j*(-206) -75 + j*(292) --385 + j*(157) --62 + j*(223) --265 + j*(-31) -153 + j*(-35) --298 + j*(-184) -78 + j*(26) --50 + j*(192) -42 + j*(150) -27 + j*(-25) -310 + j*(175) -48 + j*(-118) -100 + j*(55) -120 + j*(175) -327 + j*(-191) -65 + j*(-161) --13 + j*(94) -60 + j*(62) --109 + j*(-181) --36 + j*(-14) --128 + j*(-132) --124 + j*(-5) -88 + j*(-116) -233 + j*(-172) -124 + j*(-318) -93 + j*(-222) --46 + j*(-119) -25 + j*(115) --62 + j*(-232) -182 + j*(-144) -115 + j*(-137) -209 + j*(-123) --194 + j*(156) -141 + j*(-25) -54 + j*(-33) -228 + j*(151) -161 + j*(-208) --235 + j*(-128) -77 + j*(433) --103 + j*(186) --173 + j*(105) --28 + j*(-249) -199 + j*(255) --308 + j*(-40) -72 + j*(-93) --238 + j*(-285) -549 + j*(58) --267 + j*(-106) --11 + j*(-100) -95 + j*(41) -112 + j*(185) -17 + j*(-157) --20 + j*(163) --278 + j*(8) --92 + j*(-59) --197 + j*(37) --441 + j*(-72) --11 + j*(68) -4 + j*(-237) -166 + j*(-2) -15 + j*(-119) --309 + j*(-29) --144 + j*(-14) --230 + j*(-114) --5 + j*(151) --181 + j*(-371) -18 + j*(-228) -163 + j*(-178) -13 + j*(248) --243 + j*(-315) --116 + j*(101) -146 + j*(206) -88 + j*(60) -111 + j*(-144) -0 + j*(281) -10 + j*(-163) --59 + j*(127) -517 + j*(11) -73 + j*(35) -172 + j*(12) -47 + j*(4) --83 + j*(-124) -53 + j*(50) --148 + j*(-124) --141 + j*(238) --54 + j*(41) --139 + j*(-158) --196 + j*(374) --301 + j*(265) --39 + j*(2) -97 + j*(-139) --106 + j*(133) --305 + j*(62) -114 + j*(90) --55 + j*(-114) --122 + j*(-102) -8 + j*(-168) --252 + j*(-70) --70 + j*(42) --141 + j*(-4) --69 + j*(226) -56 + j*(244) -49 + j*(2) --57 + j*(57) --194 + j*(122) --329 + j*(-75) -167 + j*(-91) --197 + j*(279) -117 + j*(-48) -30 + j*(-26) --132 + j*(159) -332 + j*(76) -36 + j*(230) --37 + j*(-238) --40 + j*(-260) -151 + j*(91) --77 + j*(60) -98 + j*(27) -251 + j*(-101) --18 + j*(120) --93 + j*(-235) --76 + j*(8) -404 + j*(191) --8 + j*(-64) -30 + j*(58) --175 + j*(281) --102 + j*(-7) --254 + j*(144) --15 + j*(13) -393 + j*(-165) --185 + j*(-293) --86 + j*(59) --87 + j*(-224) --60 + j*(-87) -177 + j*(-240) -455 + j*(64) -78 + j*(-25) -41 + j*(-100) --71 + j*(-47) -8 + j*(138) -18 + j*(-21) --141 + j*(195) -127 + j*(185) --158 + j*(-86) --62 + j*(5) -206 + j*(103) -156 + j*(-23) -46 + j*(0) -83 + j*(119) --12 + j*(-33) --260 + j*(-20) --59 + j*(-342) -159 + j*(52) -112 + j*(228) -137 + j*(212) --153 + j*(-200) --134 + j*(-71) -262 + j*(312) --369 + j*(-21) -129 + j*(-147) --73 + j*(-161) --117 + j*(110) -110 + j*(113) --8 + j*(49) -52 + j*(296) --158 + j*(-57) --72 + j*(94) --134 + j*(-95) -41 + j*(-303) -177 + j*(-135) --338 + j*(182) --182 + j*(33) --183 + j*(97) -144 + j*(-33) --47 + j*(-262) -139 + j*(95) --286 + j*(88) -318 + j*(-64) -119 + j*(252) --46 + j*(-5) -372 + j*(201) --144 + j*(103) --52 + j*(165) -59 + j*(214) -232 + j*(-100) --237 + j*(85) --396 + j*(-92) --230 + j*(126) --81 + j*(-54) -205 + j*(71) --80 + j*(-67) -322 + j*(-10) --101 + j*(-81) --22 + j*(110) -280 + j*(-179) -26 + j*(-250) -49 + j*(143) --253 + j*(16) --140 + j*(70) -238 + j*(177) -165 + j*(27) --12 + j*(233) -281 + j*(147) -49 + j*(-413) -190 + j*(-138) --115 + j*(280) -184 + j*(-147) -174 + j*(4) --112 + j*(56) --163 + j*(-38) --260 + j*(201) -257 + j*(-362) -344 + j*(141) --185 + j*(-252) -257 + j*(135) --119 + j*(-91) --13 + j*(-37) -133 + j*(21) -72 + j*(58) -71 + j*(368) -276 + j*(279) --87 + j*(293) -46 + j*(-38) --127 + j*(-140) --55 + j*(40) -180 + j*(-16) --54 + j*(267) -59 + j*(213) -24 + j*(-54) --160 + j*(-71) --115 + j*(-206) -0 + j*(-27) -30 + j*(63) -175 + j*(48) -250 + j*(107) -141 + j*(-119) --46 + j*(-228) -141 + j*(55) --11 + j*(-161) -71 + j*(-49) -132 + j*(-453) --171 + j*(134) --240 + j*(-64) --238 + j*(-89) -215 + j*(143) -95 + j*(-177) --115 + j*(12) --98 + j*(-80) -168 + j*(-66) -83 + j*(33) --310 + j*(256) -108 + j*(-310) -206 + j*(83) -103 + j*(61) --42 + j*(-98) -117 + j*(-24) -12 + j*(66) --107 + j*(-325) --97 + j*(-29) -279 + j*(-264) --112 + j*(-161) --330 + j*(88) --315 + j*(-161) --74 + j*(-153) -102 + j*(235) --49 + j*(358) -298 + j*(-292) -170 + j*(292) -139 + j*(254) --199 + j*(-175) -238 + j*(181) --100 + j*(77) --125 + j*(382) -69 + j*(40) --155 + j*(-226) --220 + j*(-99) --39 + j*(-467) --185 + j*(-52) --100 + j*(-15) --55 + j*(84) -80 + j*(278) -52 + j*(-245) --37 + j*(-181) -194 + j*(358) -180 + j*(25) -215 + j*(-21) --254 + j*(128) -208 + j*(43) -148 + j*(-43) -80 + j*(168) -168 + j*(-79) --107 + j*(-41) -98 + j*(250) --51 + j*(-281) -81 + j*(-32) --45 + j*(-207) -95 + j*(31) -29 + j*(60) --104 + j*(-112) -16 + j*(175) -64 + j*(-142) --16 + j*(-264) -90 + j*(-200) -106 + j*(-193) --76 + j*(-26) --81 + j*(226) -4 + j*(-62) --105 + j*(-92) --64 + j*(-13) --118 + j*(-20) --76 + j*(-79) -153 + j*(52) --29 + j*(216) --237 + j*(305) --57 + j*(43) -251 + j*(-64) -65 + j*(-22) --66 + j*(-105) --46 + j*(30) --124 + j*(-200) -186 + j*(108) --303 + j*(98) -127 + j*(-165) -35 + j*(-56) --58 + j*(30) -150 + j*(155) --151 + j*(-247) --194 + j*(-41) --150 + j*(6) --230 + j*(92) --91 + j*(37) -219 + j*(-158) --185 + j*(44) -97 + j*(-40) --209 + j*(43) --160 + j*(44) -111 + j*(-115) --206 + j*(2) --380 + j*(-145) --291 + j*(185) --16 + j*(211) -65 + j*(73) --13 + j*(137) -14 + j*(68) -19 + j*(24) --10 + j*(235) -21 + j*(-56) -36 + j*(-182) --54 + j*(25) -209 + j*(-83) --146 + j*(305) -138 + j*(-47) --152 + j*(-73) -218 + j*(23) -56 + j*(-35) -267 + j*(17) -214 + j*(-84) --240 + j*(309) -98 + j*(45) -211 + j*(-54) -133 + j*(-213) -1 + j*(87) --165 + j*(78) --58 + j*(-218) -10 + j*(-103) --237 + j*(82) --180 + j*(17) --169 + j*(-69) --100 + j*(-223) -339 + j*(34) -288 + j*(-133) --148 + j*(-80) -124 + j*(-6) -278 + j*(115) -88 + j*(39) --99 + j*(-206) -54 + j*(198) --30 + j*(92) --75 + j*(-107) -237 + j*(185) --15 + j*(-160) -141 + j*(182) -129 + j*(169) -72 + j*(9) --214 + j*(236) -133 + j*(21) --25 + j*(74) --122 + j*(-70) --260 + j*(163) --24 + j*(-200) --235 + j*(45) -185 + j*(207) --279 + j*(54) --241 + j*(-18) --153 + j*(-87) --255 + j*(40) --113 + j*(-238) -369 + j*(24) -218 + j*(57) -205 + j*(637) -19 + j*(61) -66 + j*(25) --217 + j*(-431) -62 + j*(208) -269 + j*(-142) -16 + j*(122) -56 + j*(-24) --279 + j*(-170) --141 + j*(233) -339 + j*(-234) --99 + j*(-257) --145 + j*(263) -57 + j*(-175) -36 + j*(250) --94 + j*(-114) --196 + j*(13) -57 + j*(242) -18 + j*(216) --37 + j*(291) -264 + j*(-162) --219 + j*(178) -349 + j*(211) -204 + j*(-43) -21 + j*(93) -21 + j*(-221) -41 + j*(-16) --98 + j*(-230) --264 + j*(-47) -126 + j*(-108) -268 + j*(-69) -41 + j*(65) -76 + j*(301) --84 + j*(-194) --156 + j*(-68) --6 + j*(-103) --9 + j*(-292) --274 + j*(-38) --128 + j*(-166) -57 + j*(127) --155 + j*(-173) --35 + j*(-301) --120 + j*(390) --71 + j*(-32) --16 + j*(-83) --28 + j*(-132) -146 + j*(-89) --233 + j*(134) --136 + j*(-153) --62 + j*(-111) -0 + j*(-173) -240 + j*(314) --331 + j*(-113) -215 + j*(99) --129 + j*(92) -81 + j*(183) -103 + j*(-28) --305 + j*(25) -64 + j*(165) -31 + j*(-141) -503 + j*(144) --18 + j*(-52) --139 + j*(9) --247 + j*(102) --14 + j*(-35) -139 + j*(-177) --218 + j*(1) --123 + j*(-48) --13 + j*(152) -164 + j*(342) --188 + j*(-28) -102 + j*(-18) --275 + j*(-183) --140 + j*(105) --89 + j*(-166) -150 + j*(-127) -153 + j*(202) --160 + j*(98) --30 + j*(-16) -136 + j*(36) -164 + j*(165) --61 + j*(-130) -232 + j*(-411) --65 + j*(129) -184 + j*(-213) --237 + j*(134) --322 + j*(240) --18 + j*(45) -52 + j*(-71) -202 + j*(-8) --103 + j*(-185) --91 + j*(56) --245 + j*(-260) --168 + j*(260) --35 + j*(30) -57 + j*(-226) -57 + j*(49) -199 + j*(-151) -43 + j*(28) --358 + j*(64) --94 + j*(-109) -270 + j*(-82) -132 + j*(7) -206 + j*(10) -506 + j*(-12) --49 + j*(-83) --315 + j*(-318) --15 + j*(277) --157 + j*(-344) -379 + j*(221) -377 + j*(59) -308 + j*(-408) --211 + j*(228) -16 + j*(-142) --260 + j*(-234) --285 + j*(-187) -272 + j*(170) --99 + j*(209) --125 + j*(86) --326 + j*(-369) --164 + j*(-24) --109 + j*(388) --103 + j*(-238) --169 + j*(-40) -10 + j*(-123) -190 + j*(-354) --339 + j*(141) -176 + j*(-11) --105 + j*(4) --83 + j*(-327) --14 + j*(-84) -86 + j*(65) -206 + j*(100) -279 + j*(-349) --328 + j*(191) -21 + j*(-1) -77 + j*(174) -49 + j*(-45) -32 + j*(-206) --141 + j*(75) --64 + j*(33) -174 + j*(88) -328 + j*(-105) -222 + j*(400) --209 + j*(493) --165 + j*(-93) --6 + j*(126) -30 + j*(-97) --117 + j*(-136) --81 + j*(-33) -12 + j*(2) -261 + j*(93) -11 + j*(-62) -10 + j*(98) --125 + j*(-16) -141 + j*(226) -182 + j*(-117) -94 + j*(283) --136 + j*(-20) -455 + j*(-54) --87 + j*(75) --151 + j*(226) --253 + j*(54) --8 + j*(-204) --62 + j*(-136) --182 + j*(148) --16 + j*(74) --17 + j*(-224) --67 + j*(-27) -138 + j*(30) -81 + j*(71) --7 + j*(-83) -127 + j*(98) -22 + j*(-260) -312 + j*(-258) --189 + j*(31) -159 + j*(158) -240 + j*(-91) --32 + j*(-305) -78 + j*(26) -48 + j*(242) --66 + j*(117) -176 + j*(-287) --78 + j*(0) -300 + j*(119) -128 + j*(-288) -22 + j*(161) -373 + j*(192) -272 + j*(70) --50 + j*(84) -3 + j*(54) -26 + j*(86) -49 + j*(182) -46 + j*(-55) --124 + j*(188) --196 + j*(277) -37 + j*(26) --77 + j*(-10) -130 + j*(-244) --35 + j*(421) -9 + j*(219) -177 + j*(49) -48 + j*(-383) --43 + j*(141) --102 + j*(76) -132 + j*(47) --154 + j*(56) --26 + j*(-116) --93 + j*(30) --99 + j*(-182) --301 + j*(-375) -47 + j*(-53) -196 + j*(-124) --271 + j*(-64) --61 + j*(-177) --325 + j*(-323) -8 + j*(147) -32 + j*(67) --158 + j*(-103) -97 + j*(-142) -193 + j*(-113) -168 + j*(-134) -12 + j*(122) --45 + j*(172) -153 + j*(59) -271 + j*(-115) -296 + j*(-90) --117 + j*(-60) --380 + j*(-109) --173 + j*(-264) -25 + j*(-51) -484 + j*(32) --175 + j*(52) --358 + j*(212) -81 + j*(-68) -10 + j*(128) --103 + j*(-35) -44 + j*(351) -202 + j*(36) --97 + j*(279) -87 + j*(103) --70 + j*(27) -133 + j*(235) -109 + j*(199) -146 + j*(88) --90 + j*(-188) --433 + j*(-84) --101 + j*(-179) -202 + j*(-115) -209 + j*(-90) -28 + j*(103) --146 + j*(168) -128 + j*(134) -273 + j*(158) --272 + j*(169) --179 + j*(-197) --387 + j*(-228) --86 + j*(-306) -161 + j*(-260) --61 + j*(-40) --128 + j*(-26) --1 + j*(188) -133 + j*(-36) --50 + j*(41) --20 + j*(-163) -163 + j*(68) -134 + j*(183) --278 + j*(-277) -168 + j*(294) --473 + j*(-18) -25 + j*(364) -61 + j*(-151) -83 + j*(59) -45 + j*(-225) -76 + j*(105) -162 + j*(-346) -101 + j*(94) --37 + j*(-292) --23 + j*(-143) -170 + j*(49) --14 + j*(-16) -22 + j*(71) --111 + j*(-79) -188 + j*(-58) --122 + j*(-239) -252 + j*(161) --45 + j*(-11) -25 + j*(-204) -279 + j*(-64) --137 + j*(-185) --114 + j*(23) -133 + j*(185) -188 + j*(212) --41 + j*(51) -141 + j*(-110) --96 + j*(-378) -58 + j*(-146) -152 + j*(-47) -35 + j*(30) -144 + j*(-59) --202 + j*(64) --265 + j*(-29) -69 + j*(-327) --15 + j*(54) -13 + j*(-119) --33 + j*(273) --203 + j*(81) --108 + j*(275) --109 + j*(119) --165 + j*(-93) --108 + j*(309) --100 + j*(-303) -269 + j*(-175) --293 + j*(95) --129 + j*(183) -187 + j*(-76) -317 + j*(-244) -131 + j*(30) --293 + j*(-280) --96 + j*(170) -11 + j*(219) --88 + j*(-159) --386 + j*(-183) --385 + j*(141) -13 + j*(252) --184 + j*(-351) -473 + j*(213) -6 + j*(-129) -13 + j*(216) -66 + j*(1) -257 + j*(-221) -332 + j*(164) --60 + j*(74) --113 + j*(-6) --59 + j*(264) --11 + j*(37) --74 + j*(263) -80 + j*(-193) --12 + j*(-102) -74 + j*(-3) --25 + j*(-152) -358 + j*(121) -134 + j*(69) --374 + j*(77) -323 + j*(-186) -47 + j*(72) --14 + j*(-469) --23 + j*(-97) --92 + j*(264) -100 + j*(-27) -158 + j*(-268) -32 + j*(55) -291 + j*(-216) --260 + j*(194) -97 + j*(159) --21 + j*(-142) --152 + j*(-19) --64 + j*(358) -162 + j*(18) --225 + j*(90) --127 + j*(234) -64 + j*(43) -141 + j*(45) --250 + j*(9) -52 + j*(-197) -202 + j*(114) --103 + j*(90) -306 + j*(-103) -385 + j*(21) --66 + j*(-288) --187 + j*(-74) --9 + j*(-46) -420 + j*(146) --13 + j*(166) --168 + j*(81) --267 + j*(-56) -98 + j*(-157) --362 + j*(155) -339 + j*(76) -190 + j*(25) --40 + j*(324) --40 + j*(135) --176 + j*(-10) --62 + j*(-112) -42 + j*(201) --52 + j*(-45) -290 + j*(-97) -190 + j*(98) -134 + j*(-165) --162 + j*(-31) --290 + j*(92) --80 + j*(-121) --72 + j*(217) --151 + j*(-44) -42 + j*(140) -185 + j*(-230) -144 + j*(9) -188 + j*(107) --9 + j*(174) -32 + j*(-89) -387 + j*(107) -185 + j*(232) --91 + j*(40) --83 + j*(137) -114 + j*(14) -180 + j*(12) --35 + j*(318) --139 + j*(-17) --3 + j*(-109) -163 + j*(-286) --211 + j*(-83) -29 + j*(21) -401 + j*(-445) --81 + j*(-83) --98 + j*(-218) --121 + j*(-2) -115 + j*(17) -78 + j*(-435) -98 + j*(40) -304 + j*(139) -53 + j*(166) -185 + j*(130) --115 + j*(-383) --170 + j*(-74) --49 + j*(-89) -7 + j*(77) -229 + j*(-230) -91 + j*(-82) -19 + j*(60) --278 + j*(-250) --127 + j*(25) -229 + j*(-180) --57 + j*(36) --25 + j*(163) -84 + j*(-128) -59 + j*(88) --171 + j*(-7) -114 + j*(255) -35 + j*(109) --44 + j*(409) --210 + j*(-250) --69 + j*(66) --121 + j*(48) -125 + j*(-195) -107 + j*(55) --1 + j*(-103) -264 + j*(24) -35 + j*(-345) --250 + j*(-409) -195 + j*(6) --60 + j*(-27) --64 + j*(147) --33 + j*(92) --25 + j*(-93) --228 + j*(-18) --37 + j*(-191) -78 + j*(-4) --69 + j*(-494) --152 + j*(261) --6 + j*(146) --361 + j*(-142) --65 + j*(176) -244 + j*(78) --58 + j*(-261) --58 + j*(-259) --66 + j*(-286) --186 + j*(181) --257 + j*(-41) -194 + j*(354) -47 + j*(93) --121 + j*(31) -136 + j*(-87) -10 + j*(190) --272 + j*(-148) --107 + j*(-56) -115 + j*(-47) --53 + j*(-172) -45 + j*(-48) -347 + j*(-141) -66 + j*(-78) --156 + j*(122) -50 + j*(-180) -217 + j*(-42) --210 + j*(-83) -228 + j*(189) -583 + j*(-493) -196 + j*(153) -40 + j*(-85) -105 + j*(8) --49 + j*(-282) -164 + j*(-246) --35 + j*(-301) -129 + j*(252) --268 + j*(125) --144 + j*(116) --309 + j*(112) -40 + j*(-140) -42 + j*(-145) -39 + j*(161) --340 + j*(243) --55 + j*(-122) -167 + j*(135) --185 + j*(122) -66 + j*(-51) -200 + j*(46) -67 + j*(-173) --50 + j*(126) -536 + j*(-277) -66 + j*(-58) --182 + j*(208) --59 + j*(-201) -253 + j*(46) --20 + j*(-202) -66 + j*(269) -395 + j*(128) --171 + j*(263) --45 + j*(-102) --135 + j*(13) --194 + j*(109) --115 + j*(313) -21 + j*(310) --22 + j*(-176) --59 + j*(-142) -274 + j*(33) -50 + j*(-194) --39 + j*(210) --163 + j*(-13) --247 + j*(316) -163 + j*(-173) -54 + j*(-386) -49 + j*(293) --6 + j*(286) --254 + j*(-59) --308 + j*(-129) -141 + j*(-104) --262 + j*(-76) --92 + j*(346) -318 + j*(-88) -134 + j*(248) --27 + j*(-118) -119 + j*(145) --185 + j*(-234) --141 + j*(-91) --95 + j*(-129) -151 + j*(-233) --91 + j*(-215) --105 + j*(-1) --32 + j*(-80) -133 + j*(-57) --52 + j*(-29) --103 + j*(-84) --65 + j*(-89) --83 + j*(38) --42 + j*(-209) --243 + j*(-137) --74 + j*(-73) --167 + j*(33) --197 + j*(-66) -12 + j*(-21) -88 + j*(-200) -129 + j*(108) -335 + j*(71) -54 + j*(-274) --129 + j*(-361) -338 + j*(-28) -35 + j*(-118) --44 + j*(-242) --66 + j*(-45) --290 + j*(-136) --23 + j*(180) -176 + j*(86) -63 + j*(-119) -68 + j*(-148) --366 + j*(-110) -138 + j*(86) --22 + j*(80) -72 + j*(28) --49 + j*(-218) -64 + j*(14) -364 + j*(-48) -221 + j*(-61) -212 + j*(175) --34 + j*(199) --25 + j*(135) -239 + j*(-129) --253 + j*(-223) -103 + j*(148) -100 + j*(199) -331 + j*(103) -256 + j*(-104) -194 + j*(78) -170 + j*(-54) --51 + j*(83) --112 + j*(288) -298 + j*(88) --196 + j*(-251) --5 + j*(33) -104 + j*(-231) --233 + j*(-22) -115 + j*(-112) -15 + j*(7) -147 + j*(-501) -223 + j*(60) --243 + j*(-366) --35 + j*(100) --64 + j*(-82) --236 + j*(-47) -137 + j*(-5) -31 + j*(-117) -401 + j*(436) --192 + j*(-45) -78 + j*(-392) --258 + j*(263) --303 + j*(-162) -119 + j*(169) -211 + j*(58) --53 + j*(117) --28 + j*(-269) -107 + j*(-180) -107 + j*(-92) --80 + j*(22) -356 + j*(127) --168 + j*(91) --199 + j*(-310) --117 + j*(-108) --193 + j*(-369) -60 + j*(156) -62 + j*(77) --21 + j*(-73) --219 + j*(-141) --418 + j*(11) --44 + j*(-158) -297 + j*(-14) -183 + j*(285) --77 + j*(-115) --92 + j*(-203) -302 + j*(-100) -234 + j*(-197) -275 + j*(88) -57 + j*(-214) -52 + j*(-255) -164 + j*(214) -119 + j*(-187) -117 + j*(86) --3 + j*(340) -95 + j*(-66) -32 + j*(-25) --200 + j*(105) --76 + j*(126) -91 + j*(37) --245 + j*(-36) --120 + j*(77) -120 + j*(-119) --99 + j*(-166) --4 + j*(137) -41 + j*(151) --182 + j*(35) --151 + j*(-89) --63 + j*(-212) -269 + j*(164) -284 + j*(163) -123 + j*(87) --55 + j*(-116) -68 + j*(-134) --62 + j*(-74) -57 + j*(100) -204 + j*(159) -255 + j*(182) -40 + j*(-157) --81 + j*(118) --11 + j*(-113) -168 + j*(-326) -158 + j*(8) --139 + j*(-2) -103 + j*(-64) -54 + j*(606) -202 + j*(32) --240 + j*(-212) --236 + j*(-55) -25 + j*(-208) -124 + j*(-163) -127 + j*(-118) --194 + j*(50) -23 + j*(106) -178 + j*(-280) -92 + j*(-33) --42 + j*(126) -208 + j*(159) --103 + j*(-33) -247 + j*(70) --337 + j*(253) --83 + j*(-166) --199 + j*(12) --92 + j*(542) -178 + j*(-195) --115 + j*(-338) -146 + j*(82) --163 + j*(-86) --88 + j*(-90) -19 + j*(-390) --59 + j*(-48) -81 + j*(165) -103 + j*(-173) -47 + j*(-240) --453 + j*(-52) --102 + j*(234) --272 + j*(161) -81 + j*(-75) --143 + j*(-223) --126 + j*(-250) -134 + j*(-209) -45 + j*(-143) --290 + j*(-23) --88 + j*(14) -382 + j*(-177) --407 + j*(-16) --9 + j*(-69) -401 + j*(-166) -127 + j*(-6) -149 + j*(-99) --124 + j*(-21) -17 + j*(-229) --5 + j*(23) --173 + j*(34) -34 + j*(59) -204 + j*(-1) -48 + j*(253) -247 + j*(154) --158 + j*(172) --81 + j*(340) --23 + j*(-86) --18 + j*(26) -6 + j*(-112) --252 + j*(-152) -186 + j*(148) --199 + j*(76) -330 + j*(6) -13 + j*(-215) --279 + j*(-163) -52 + j*(-40) --167 + j*(-231) --236 + j*(129) -78 + j*(-25) -147 + j*(-44) -119 + j*(125) --149 + j*(-324) -1 + j*(-77) --201 + j*(-49) -250 + j*(-146) -15 + j*(-36) -56 + j*(-78) --35 + j*(-8) --110 + j*(14) -170 + j*(-251) --460 + j*(-7) --32 + j*(-224) --18 + j*(86) --17 + j*(-165) -417 + j*(-276) --87 + j*(72) --205 + j*(-112) -0 + j*(-154) --8 + j*(-245) -147 + j*(27) -89 + j*(-115) --16 + j*(-88) --187 + j*(-146) --93 + j*(8) --11 + j*(181) --159 + j*(4) --132 + j*(92) --23 + j*(-123) -223 + j*(69) --5 + j*(249) --127 + j*(291) -95 + j*(4) -59 + j*(228) -75 + j*(-275) --171 + j*(11) --136 + j*(-105) --198 + j*(204) --57 + j*(5) -3 + j*(-324) --538 + j*(-66) -74 + j*(-358) -467 + j*(20) --421 + j*(-13) -46 + j*(-384) --553 + j*(-285) -178 + j*(18) --197 + j*(97) -333 + j*(-331) --301 + j*(-172) -50 + j*(-204) -291 + j*(331) --132 + j*(-193) --199 + j*(382) --44 + j*(-281) -33 + j*(177) -18 + j*(624) -291 + j*(-469) --192 + j*(71) --414 + j*(254) --331 + j*(-499) -281 + j*(-560) --112 + j*(-367) --390 + j*(-414) -274 + j*(-482) -373 + j*(-433) -320 + j*(128) -250 + j*(-570) --4 + j*(364) -345 + j*(329) --415 + j*(450) -384 + j*(-269) --269 + j*(337) --714 + j*(-90) --144 + j*(-327) -92 + j*(-220) --202 + j*(-617) -368 + j*(187) --391 + j*(445) --446 + j*(485) -606 + j*(-561) --156 + j*(266) -346 + j*(262) -44 + j*(288) -6 + j*(132) -199 + j*(107) -517 + j*(165) -59 + j*(218) -371 + j*(-624) -278 + j*(0) --479 + j*(-395) -390 + j*(-21) -233 + j*(52) --342 + j*(371) --434 + j*(473) --187 + j*(-260) --327 + j*(412) --393 + j*(179) --523 + j*(-187) --343 + j*(-66) -295 + j*(193) -132 + j*(-379) -298 + j*(-465) --434 + j*(26) --532 + j*(284) --207 + j*(-152) --286 + j*(412) --233 + j*(-143) -49 + j*(185) -11 + j*(10) --176 + j*(527) -395 + j*(203) --45 + j*(356) -264 + j*(-517) -189 + j*(-214) -325 + j*(-169) --23 + j*(114) --362 + j*(190) --424 + j*(-215) -442 + j*(496) --311 + j*(-489) -347 + j*(19) --66 + j*(-206) --299 + j*(-675) --133 + j*(-135) -369 + j*(312) --94 + j*(467) -222 + j*(-23) -177 + j*(240) --163 + j*(-114) -278 + j*(-13) -168 + j*(523) --314 + j*(127) --484 + j*(119) -298 + j*(522) --288 + j*(-101) --369 + j*(448) -62 + j*(138) -74 + j*(176) --442 + j*(-165) -25 + j*(-23) -540 + j*(622) -92 + j*(82) --477 + j*(187) -134 + j*(-74) -308 + j*(176) -213 + j*(-274) --223 + j*(-270) --400 + j*(393) -544 + j*(-454) -337 + j*(-287) --313 + j*(466) -304 + j*(397) -118 + j*(-298) --496 + j*(358) -58 + j*(-314) --18 + j*(56) --37 + j*(-183) -85 + j*(-219) -470 + j*(-586) --557 + j*(-581) -425 + j*(194) --148 + j*(-387) -111 + j*(66) -433 + j*(412) -330 + j*(-301) -284 + j*(-236) --71 + j*(156) -243 + j*(-194) -323 + j*(692) -49 + j*(547) --98 + j*(232) --141 + j*(-212) -57 + j*(250) -313 + j*(-370) --641 + j*(-368) --259 + j*(-291) --16 + j*(-18) --689 + j*(241) --308 + j*(-279) -392 + j*(-391) -271 + j*(-156) -40 + j*(334) -84 + j*(-208) --247 + j*(123) -122 + j*(-320) -293 + j*(-576) --299 + j*(446) --459 + j*(-285) --474 + j*(-351) -119 + j*(129) --264 + j*(110) --203 + j*(411) -245 + j*(52) -215 + j*(-194) --147 + j*(333) --242 + j*(-580) -255 + j*(140) -107 + j*(-214) -223 + j*(139) --246 + j*(-601) -219 + j*(-79) -232 + j*(-344) -250 + j*(-248) -76 + j*(64) -380 + j*(-157) -125 + j*(325) --306 + j*(257) -317 + j*(199) --364 + j*(435) --135 + j*(-126) -47 + j*(-95) --303 + j*(-332) --411 + j*(416) --205 + j*(-384) -341 + j*(-59) --47 + j*(-214) --64 + j*(-122) -284 + j*(352) --300 + j*(270) -419 + j*(175) -201 + j*(-445) -269 + j*(409) -381 + j*(225) -262 + j*(487) --52 + j*(-374) -33 + j*(-332) --221 + j*(-178) -57 + j*(-252) --325 + j*(325) -218 + j*(546) --151 + j*(0) -262 + j*(-284) -240 + j*(428) -144 + j*(123) -254 + j*(-41) --361 + j*(365) --5 + j*(288) -392 + j*(-202) -316 + j*(238) -296 + j*(165) -16 + j*(468) -36 + j*(290) --267 + j*(-337) -119 + j*(396) --428 + j*(401) --301 + j*(-145) -288 + j*(-189) -506 + j*(-230) --116 + j*(-116) --217 + j*(-225) -171 + j*(-210) -444 + j*(-202) -223 + j*(124) --432 + j*(522) -133 + j*(235) --234 + j*(-372) --84 + j*(-268) --142 + j*(-271) -189 + j*(148) -67 + j*(16) -342 + j*(278) -355 + j*(319) -115 + j*(-101) -631 + j*(-556) -267 + j*(344) --472 + j*(-622) --483 + j*(433) -327 + j*(373) --462 + j*(457) --331 + j*(139) --59 + j*(-136) -276 + j*(-262) --57 + j*(182) --319 + j*(168) --277 + j*(132) -351 + j*(-30) --111 + j*(260) --291 + j*(560) -425 + j*(622) -221 + j*(-26) -121 + j*(54) --103 + j*(271) --273 + j*(-501) -608 + j*(-200) --373 + j*(-40) -103 + j*(-91) -33 + j*(107) --253 + j*(302) -208 + j*(-200) --401 + j*(78) --143 + j*(-327) -354 + j*(-397) --85 + j*(-421) -280 + j*(-222) -320 + j*(-242) -283 + j*(-122) --399 + j*(407) --46 + j*(9) -244 + j*(171) -462 + j*(-53) --617 + j*(-304) --309 + j*(115) -493 + j*(-261) --403 + j*(140) --300 + j*(86) -643 + j*(4) -339 + j*(-296) --363 + j*(-57) --72 + j*(472) -199 + j*(-41) --198 + j*(212) -369 + j*(185) -228 + j*(-564) --215 + j*(-262) --423 + j*(-37) --159 + j*(371) --373 + j*(-308) --371 + j*(241) --204 + j*(-335) -68 + j*(182) --284 + j*(-345) --332 + j*(-184) -418 + j*(255) -3 + j*(-298) -437 + j*(219) -66 + j*(-67) -98 + j*(-235) --384 + j*(288) --322 + j*(271) --377 + j*(-383) -517 + j*(-313) -53 + j*(211) -356 + j*(158) -131 + j*(23) --161 + j*(-13) -284 + j*(-383) -414 + j*(50) -295 + j*(-61) -239 + j*(-342) -289 + j*(-161) -458 + j*(-262) --348 + j*(-588) --573 + j*(215) -266 + j*(463) -344 + j*(-51) -4 + j*(383) -226 + j*(-94) -306 + j*(-347) -206 + j*(11) -347 + j*(151) --305 + j*(337) -433 + j*(302) --28 + j*(527) --534 + j*(-516) -248 + j*(206) -33 + j*(70) --18 + j*(-231) -231 + j*(-226) --456 + j*(-378) -112 + j*(-158) --90 + j*(-523) -52 + j*(-177) --156 + j*(-113) -46 + j*(268) -22 + j*(422) --191 + j*(-325) --315 + j*(-511) --562 + j*(-180) --69 + j*(-325) -591 + j*(288) --554 + j*(337) --305 + j*(358) --340 + j*(-383) --443 + j*(412) -98 + j*(-349) --403 + j*(219) -401 + j*(-107) -209 + j*(-242) --416 + j*(307) -470 + j*(-292) -249 + j*(344) -84 + j*(520) --99 + j*(-9) --381 + j*(240) -52 + j*(-255) --315 + j*(228) -165 + j*(-340) --385 + j*(-367) -378 + j*(11) -486 + j*(-447) -574 + j*(-212) --550 + j*(-66) -296 + j*(443) --421 + j*(-38) --15 + j*(334) -156 + j*(-60) -291 + j*(184) --148 + j*(-100) --99 + j*(294) -214 + j*(76) -349 + j*(-234) -291 + j*(263) --121 + j*(-279) --119 + j*(-69) -187 + j*(204) -340 + j*(-244) --297 + j*(244) --8 + j*(-47) --105 + j*(-7) --196 + j*(-63) --105 + j*(35) -405 + j*(69) -423 + j*(219) --462 + j*(-112) --197 + j*(-422) -224 + j*(81) --612 + j*(71) -363 + j*(209) -133 + j*(-302) -235 + j*(418) --315 + j*(479) --166 + j*(-6) --97 + j*(140) -278 + j*(451) --301 + j*(212) --412 + j*(-291) -446 + j*(224) -108 + j*(-417) -487 + j*(269) --527 + j*(156) --550 + j*(-249) -543 + j*(424) --126 + j*(57) --230 + j*(-80) --40 + j*(-153) --22 + j*(-342) --75 + j*(-334) -339 + j*(-45) --105 + j*(36) -151 + j*(81) --457 + j*(499) -207 + j*(-512) --276 + j*(462) --246 + j*(-299) --155 + j*(-314) --18 + j*(-281) -233 + j*(-358) -564 + j*(-344) --448 + j*(-518) -477 + j*(84) --371 + j*(-276) -453 + j*(187) --252 + j*(-148) -459 + j*(370) --31 + j*(-509) --215 + j*(-175) --177 + j*(-291) --182 + j*(-204) -298 + j*(47) -200 + j*(-255) --353 + j*(-530) -182 + j*(-202) --296 + j*(-480) -370 + j*(-175) --250 + j*(-131) --74 + j*(-313) --115 + j*(-626) -326 + j*(274) --16 + j*(-218) --151 + j*(-180) --474 + j*(374) -378 + j*(-107) -141 + j*(245) -113 + j*(-241) --526 + j*(1) --300 + j*(-199) -550 + j*(-174) -392 + j*(166) -110 + j*(-38) -301 + j*(-351) -284 + j*(-59) -223 + j*(-526) --282 + j*(608) -317 + j*(332) --503 + j*(-453) --366 + j*(518) -349 + j*(1) -310 + j*(279) --163 + j*(-223) --21 + j*(-283) -443 + j*(-171) -262 + j*(-201) -317 + j*(441) -75 + j*(-129) --223 + j*(223) -296 + j*(91) --455 + j*(-91) --651 + j*(175) -359 + j*(-354) --51 + j*(512) -540 + j*(-234) --161 + j*(-114) -349 + j*(-91) --20 + j*(290) --208 + j*(-203) --25 + j*(161) --315 + j*(373) -286 + j*(-8) -125 + j*(395) --95 + j*(53) -332 + j*(-238) --211 + j*(-252) --69 + j*(-207) --617 + j*(268) --103 + j*(356) --131 + j*(393) --310 + j*(-280) --245 + j*(-274) --2 + j*(-759) --375 + j*(-166) --215 + j*(182) -315 + j*(230) --190 + j*(158) --446 + j*(333) -226 + j*(355) -344 + j*(-258) -16 + j*(-428) --372 + j*(301) -393 + j*(189) -293 + j*(-177) -455 + j*(-136) --35 + j*(-170) -16 + j*(-351) --16 + j*(-304) --127 + j*(205) --550 + j*(-288) --10 + j*(-56) --173 + j*(-178) --307 + j*(164) --329 + j*(175) --215 + j*(-426) -397 + j*(211) -289 + j*(-257) --272 + j*(23) --107 + j*(-281) -179 + j*(168) -26 + j*(-535) -23 + j*(234) -302 + j*(392) --164 + j*(-396) -52 + j*(231) -194 + j*(-21) --352 + j*(-203) --338 + j*(146) --677 + j*(-162) --191 + j*(-365) --387 + j*(493) --414 + j*(242) --103 + j*(243) --315 + j*(-6) --612 + j*(210) -41 + j*(-360) --133 + j*(-148) --368 + j*(241) -54 + j*(-62) -398 + j*(-445) --71 + j*(-591) -98 + j*(273) --729 + j*(338) --323 + j*(-267) -355 + j*(-348) -163 + j*(510) -508 + j*(-466) --651 + j*(-209) -189 + j*(168) -487 + j*(150) -364 + j*(111) -267 + j*(-54) -427 + j*(211) --412 + j*(594) --238 + j*(-31) --233 + j*(328) -192 + j*(115) -305 + j*(297) -484 + j*(436) --35 + j*(180) --129 + j*(-513) --51 + j*(-513) --398 + j*(-67) -162 + j*(373) -638 + j*(376) -641 + j*(-561) --204 + j*(-426) -551 + j*(-218) --161 + j*(556) -474 + j*(226) --243 + j*(-293) -16 + j*(-136) --474 + j*(-295) --490 + j*(-260) -252 + j*(-169) --363 + j*(209) --151 + j*(457) --361 + j*(-232) --168 + j*(460) -32 + j*(-496) --92 + j*(-243) --503 + j*(-238) -367 + j*(148) --56 + j*(258) --156 + j*(98) --250 + j*(-78) --107 + j*(-18) -298 + j*(257) --404 + j*(-225) --339 + j*(-220) --61 + j*(-391) --600 + j*(-141) -304 + j*(-457) --280 + j*(146) -206 + j*(421) -355 + j*(709) -153 + j*(225) -124 + j*(-206) -373 + j*(-447) --442 + j*(88) -269 + j*(-115) --335 + j*(-300) --158 + j*(-78) --320 + j*(-414) -491 + j*(-345) -559 + j*(252) --67 + j*(-332) --394 + j*(-370) -242 + j*(-639) --349 + j*(286) -98 + j*(57) -506 + j*(286) -117 + j*(-76) --506 + j*(47) --100 + j*(156) --59 + j*(-168) -162 + j*(363) --142 + j*(298) -110 + j*(139) -163 + j*(184) --107 + j*(-296) -40 + j*(231) --26 + j*(-117) --184 + j*(8) -156 + j*(-24) --98 + j*(-288) -192 + j*(-55) --138 + j*(-66) -161 + j*(276) -337 + j*(-55) -122 + j*(-122) -233 + j*(-233) --29 + j*(-118) --36 + j*(0) --259 + j*(5) -63 + j*(18) --158 + j*(-301) --95 + j*(-240) -549 + j*(309) -184 + j*(53) --141 + j*(328) --11 + j*(258) --41 + j*(237) --107 + j*(35) --265 + j*(-267) -205 + j*(-198) --274 + j*(284) --211 + j*(-33) --326 + j*(-124) --64 + j*(-79) --161 + j*(-294) -122 + j*(32) --248 + j*(-27) --3 + j*(-115) --145 + j*(-153) --308 + j*(35) -138 + j*(-127) --254 + j*(-220) --139 + j*(49) --33 + j*(-45) -41 + j*(23) -4 + j*(-356) --192 + j*(50) --81 + j*(200) -157 + j*(266) -110 + j*(252) -51 + j*(-231) --297 + j*(-110) --142 + j*(-7) --208 + j*(13) --236 + j*(-299) --43 + j*(190) -312 + j*(-10) -157 + j*(-322) -171 + j*(-177) --15 + j*(-80) --320 + j*(103) --58 + j*(208) -192 + j*(-77) -424 + j*(-43) -83 + j*(56) -218 + j*(83) -46 + j*(-98) --73 + j*(74) --149 + j*(35) --199 + j*(47) --54 + j*(-18) --68 + j*(136) -327 + j*(240) --45 + j*(337) --107 + j*(-88) --52 + j*(224) -238 + j*(58) --213 + j*(-77) -105 + j*(56) -163 + j*(-331) -119 + j*(-413) --66 + j*(-121) --112 + j*(176) -93 + j*(35) -199 + j*(98) -177 + j*(-56) --216 + j*(-6) --44 + j*(-34) --244 + j*(-201) -53 + j*(-68) -133 + j*(149) -85 + j*(179) --88 + j*(-4) --91 + j*(28) --173 + j*(16) --13 + j*(135) --147 + j*(120) --85 + j*(-152) -24 + j*(-194) --226 + j*(-117) --8 + j*(120) -301 + j*(350) -110 + j*(-192) --210 + j*(-33) --57 + j*(-59) --57 + j*(-199) -71 + j*(-110) -6 + j*(-235) --84 + j*(100) -38 + j*(-43) --40 + j*(151) --187 + j*(224) --156 + j*(138) -148 + j*(-41) -204 + j*(-564) -144 + j*(-85) -16 + j*(-325) --55 + j*(78) --21 + j*(-2) -77 + j*(152) --99 + j*(-4) --256 + j*(228) -221 + j*(0) --71 + j*(226) --83 + j*(-78) --5 + j*(173) --42 + j*(-68) -116 + j*(-40) -44 + j*(-258) --39 + j*(-39) --7 + j*(-173) --223 + j*(-71) -40 + j*(89) --86 + j*(-344) --243 + j*(190) -286 + j*(48) --284 + j*(227) -156 + j*(98) -180 + j*(-112) --327 + j*(-141) -180 + j*(11) --76 + j*(-96) --55 + j*(-71) --104 + j*(-48) -276 + j*(-40) --4 + j*(-30) -281 + j*(-175) -425 + j*(192) -33 + j*(-87) -279 + j*(42) --97 + j*(-129) -76 + j*(-5) -26 + j*(69) -48 + j*(-472) --218 + j*(-209) --143 + j*(-159) --59 + j*(1) -221 + j*(25) --95 + j*(32) --69 + j*(79) -95 + j*(-206) -159 + j*(-54) --121 + j*(107) --23 + j*(33) --68 + j*(-163) -40 + j*(-171) -190 + j*(-384) --162 + j*(-95) -23 + j*(-211) --136 + j*(0) --46 + j*(-2) -381 + j*(-231) -128 + j*(-233) --30 + j*(-272) --98 + j*(86) --109 + j*(-287) --30 + j*(-47) --94 + j*(235) --144 + j*(0) -257 + j*(210) --68 + j*(-23) -195 + j*(123) --221 + j*(122) -244 + j*(110) --126 + j*(-84) -59 + j*(-195) --64 + j*(305) -186 + j*(74) -85 + j*(-304) --126 + j*(96) -245 + j*(165) -23 + j*(-156) -267 + j*(-207) --306 + j*(-105) --195 + j*(131) --52 + j*(-120) -13 + j*(-123) --27 + j*(-401) -51 + j*(-105) --214 + j*(121) --68 + j*(-316) -64 + j*(83) --260 + j*(-67) --200 + j*(66) --270 + j*(108) --496 + j*(-64) --40 + j*(-259) --36 + j*(365) -29 + j*(61) -271 + j*(139) --46 + j*(-204) -112 + j*(301) -73 + j*(-66) -211 + j*(-33) -24 + j*(161) --153 + j*(-43) -4 + j*(-89) -107 + j*(202) --52 + j*(-315) -23 + j*(59) --80 + j*(-99) -115 + j*(-133) -127 + j*(-4) -56 + j*(278) --90 + j*(17) --215 + j*(176) -39 + j*(-146) --180 + j*(21) --135 + j*(146) -297 + j*(-195) --173 + j*(13) -227 + j*(153) -107 + j*(-227) --42 + j*(94) --177 + j*(176) -157 + j*(40) --243 + j*(30) --65 + j*(-271) --162 + j*(218) -574 + j*(-124) -64 + j*(-87) --106 + j*(21) --64 + j*(-85) -105 + j*(78) -170 + j*(252) -171 + j*(-236) -301 + j*(157) -257 + j*(-142) --198 + j*(127) -8 + j*(402) --31 + j*(137) --168 + j*(-62) -331 + j*(-171) -95 + j*(-11) -260 + j*(-33) -358 + j*(-293) --36 + j*(63) --6 + j*(151) -177 + j*(-247) -60 + j*(-130) -199 + j*(49) --54 + j*(83) -0 + j*(27) --158 + j*(-120) -190 + j*(-147) --168 + j*(138) -161 + j*(-16) --5 + j*(14) --260 + j*(-122) --65 + j*(118) --136 + j*(-20) -97 + j*(0) --78 + j*(0) -89 + j*(-169) -141 + j*(-215) --119 + j*(191) -114 + j*(-15) --366 + j*(300) --267 + j*(373) --71 + j*(211) -220 + j*(136) -3 + j*(91) -170 + j*(275) -159 + j*(-59) --163 + j*(-139) --148 + j*(-9) -161 + j*(321) -167 + j*(26) --87 + j*(-114) --143 + j*(33) -47 + j*(145) -30 + j*(-80) -64 + j*(-204) -70 + j*(-93) --183 + j*(37) --71 + j*(-274) --81 + j*(-93) -243 + j*(197) --277 + j*(-307) --103 + j*(-231) -32 + j*(168) -18 + j*(-4) -320 + j*(267) --28 + j*(-4) -64 + j*(195) --165 + j*(-17) --72 + j*(-80) --83 + j*(236) --95 + j*(-298) --310 + j*(4) -43 + j*(-100) -219 + j*(-225) -99 + j*(184) --158 + j*(-57) --32 + j*(-35) --405 + j*(-144) -329 + j*(9) -191 + j*(47) --65 + j*(98) --28 + j*(-207) --56 + j*(103) --9 + j*(30) --59 + j*(249) --161 + j*(-89) -105 + j*(-37) --136 + j*(-25) --461 + j*(-19) -238 + j*(-184) --49 + j*(-118) --171 + j*(-199) -208 + j*(-146) --117 + j*(-15) --72 + j*(192) -351 + j*(-381) --117 + j*(-57) --37 + j*(-335) --4 + j*(-30) --269 + j*(-141) -351 + j*(107) --214 + j*(-186) -154 + j*(-385) --10 + j*(-100) --200 + j*(-194) -120 + j*(-171) -16 + j*(-36) --6 + j*(64) -53 + j*(-182) --21 + j*(66) --244 + j*(-162) --187 + j*(107) -257 + j*(6) -254 + j*(183) -21 + j*(-123) --260 + j*(-235) --198 + j*(208) -67 + j*(-178) --156 + j*(171) -23 + j*(-328) -50 + j*(-82) -273 + j*(91) --465 + j*(11) --252 + j*(-271) -66 + j*(159) --349 + j*(-22) --38 + j*(-395) -63 + j*(-30) --83 + j*(-186) --167 + j*(-312) -231 + j*(17) -168 + j*(-475) -216 + j*(-16) --141 + j*(-285) --185 + j*(72) -88 + j*(-3) --132 + j*(-122) -63 + j*(245) -158 + j*(-104) --301 + j*(-276) --28 + j*(226) -129 + j*(40) --146 + j*(-64) --306 + j*(-209) -35 + j*(50) -390 + j*(30) --264 + j*(-94) --201 + j*(30) -4 + j*(21) --325 + j*(-134) --270 + j*(-317) -402 + j*(4) --135 + j*(181) -221 + j*(69) --272 + j*(-63) --79 + j*(169) --31 + j*(249) -25 + j*(238) -69 + j*(39) -38 + j*(119) --13 + j*(54) -218 + j*(-204) --118 + j*(-271) --123 + j*(-87) --215 + j*(-211) -8 + j*(-20) --113 + j*(-134) -118 + j*(330) -184 + j*(52) --52 + j*(8) -170 + j*(-322) -59 + j*(-35) --247 + j*(372) --42 + j*(-73) -119 + j*(111) --25 + j*(-49) --2 + j*(-87) --310 + j*(-179) -250 + j*(70) --49 + j*(18) -100 + j*(-186) --135 + j*(28) --71 + j*(153) -45 + j*(428) -3 + j*(-249) --119 + j*(111) -321 + j*(223) -25 + j*(-214) -199 + j*(-301) -36 + j*(-147) -182 + j*(-100) -138 + j*(-7) --115 + j*(-452) -147 + j*(52) -31 + j*(-32) --359 + j*(243) --57 + j*(-26) -288 + j*(-342) --114 + j*(362) --314 + j*(-102) --130 + j*(-46) -90 + j*(184) -46 + j*(-83) --231 + j*(151) --25 + j*(-37) --51 + j*(-51) --491 + j*(88) --45 + j*(141) -62 + j*(-93) --115 + j*(189) --167 + j*(556) --111 + j*(-173) --148 + j*(-122) --70 + j*(-202) -226 + j*(315) -47 + j*(82) -107 + j*(92) --71 + j*(159) --201 + j*(96) --279 + j*(312) -178 + j*(-182) -21 + j*(30) -93 + j*(-142) -330 + j*(-162) -88 + j*(49) -91 + j*(118) --88 + j*(186) -157 + j*(76) --174 + j*(79) -172 + j*(-34) -175 + j*(-133) --195 + j*(-25) -100 + j*(-73) -237 + j*(213) --206 + j*(-190) -209 + j*(-362) --407 + j*(407) --188 + j*(88) --54 + j*(264) --172 + j*(-100) -127 + j*(-121) --132 + j*(-37) --45 + j*(96) -221 + j*(111) -167 + j*(-11) -57 + j*(19) -119 + j*(-85) --74 + j*(69) -12 + j*(-302) --69 + j*(-177) --21 + j*(181) --117 + j*(157) -82 + j*(328) -393 + j*(29) -186 + j*(77) -371 + j*(-147) -93 + j*(-47) --169 + j*(-63) --48 + j*(215) -9 + j*(-59) -73 + j*(-226) --295 + j*(-11) --247 + j*(158) --114 + j*(-120) --83 + j*(-57) -53 + j*(-2) --151 + j*(-27) --251 + j*(-245) --193 + j*(-12) -31 + j*(-63) -235 + j*(208) -53 + j*(-342) -138 + j*(-112) -93 + j*(-262) -5 + j*(65) --266 + j*(-119) --149 + j*(-166) --25 + j*(38) -184 + j*(7) --290 + j*(-71) -157 + j*(293) --90 + j*(-56) -458 + j*(-84) --99 + j*(-19) -164 + j*(153) -224 + j*(174) --101 + j*(-18) --81 + j*(154) -158 + j*(154) --127 + j*(-254) -175 + j*(-91) -292 + j*(21) --170 + j*(0) -148 + j*(-99) --146 + j*(133) -136 + j*(121) -114 + j*(-186) --29 + j*(60) -39 + j*(108) --83 + j*(-29) -25 + j*(254) --4 + j*(-291) -28 + j*(199) --47 + j*(-40) --95 + j*(203) --223 + j*(18) -109 + j*(-144) --82 + j*(-18) -148 + j*(302) -42 + j*(58) -291 + j*(205) -69 + j*(25) --135 + j*(-63) -73 + j*(-18) --325 + j*(-216) --100 + j*(62) --17 + j*(-175) --198 + j*(93) --25 + j*(216) -92 + j*(-165) -122 + j*(-248) -165 + j*(166) -121 + j*(85) -81 + j*(-57) -105 + j*(167) -211 + j*(-134) -18 + j*(-106) --33 + j*(-170) -73 + j*(-61) -286 + j*(-19) -2 + j*(286) --436 + j*(426) --118 + j*(-88) --47 + j*(-100) --127 + j*(266) -58 + j*(-47) --15 + j*(210) -117 + j*(130) --325 + j*(146) -91 + j*(108) -127 + j*(-89) -41 + j*(-191) --69 + j*(283) --24 + j*(-206) --237 + j*(-129) -24 + j*(1) --15 + j*(188) -159 + j*(-438) --153 + j*(177) -91 + j*(84) -196 + j*(99) --199 + j*(-139) --26 + j*(161) --98 + j*(-145) -139 + j*(208) -8 + j*(-177) -106 + j*(83) -107 + j*(-57) --309 + j*(-213) --96 + j*(16) -88 + j*(-123) --114 + j*(145) -238 + j*(-22) -46 + j*(-329) -156 + j*(-65) --183 + j*(112) -61 + j*(-93) -11 + j*(154) -47 + j*(8) --110 + j*(-246) --185 + j*(-25) -383 + j*(-152) -6 + j*(-38) -162 + j*(-64) --345 + j*(178) --4 + j*(-176) --76 + j*(49) -50 + j*(-157) --230 + j*(-141) --103 + j*(-71) -286 + j*(134) --431 + j*(-79) -153 + j*(34) --320 + j*(-55) -178 + j*(292) --25 + j*(-117) -189 + j*(57) -158 + j*(105) --108 + j*(-551) -170 + j*(-34) --298 + j*(-87) -187 + j*(-165) -69 + j*(59) --166 + j*(453) -111 + j*(-119) -172 + j*(-110) --185 + j*(158) --131 + j*(-267) --54 + j*(-285) --57 + j*(65) -94 + j*(-38) -382 + j*(-139) --119 + j*(-199) --252 + j*(48) --190 + j*(421) --119 + j*(30) -165 + j*(236) -77 + j*(42) -14 + j*(210) --52 + j*(-196) -144 + j*(-216) -28 + j*(99) --242 + j*(151) --19 + j*(-17) -62 + j*(-230) -146 + j*(130) --67 + j*(-202) -158 + j*(-134) --318 + j*(192) -48 + j*(-28) --322 + j*(180) --263 + j*(187) -58 + j*(226) --1 + j*(96) -8 + j*(304) --31 + j*(-8) -214 + j*(-35) --35 + j*(-71) --22 + j*(-124) --321 + j*(-234) -305 + j*(-367) --170 + j*(-57) --206 + j*(124) --64 + j*(-117) -35 + j*(-8) --74 + j*(-139) --81 + j*(200) -355 + j*(189) -115 + j*(158) --22 + j*(1) --117 + j*(319) -48 + j*(193) --66 + j*(-28) --78 + j*(-221) -77 + j*(204) --308 + j*(187) --373 + j*(223) --246 + j*(224) -277 + j*(147) -64 + j*(-37) --13 + j*(-129) -6 + j*(-28) -80 + j*(15) -173 + j*(60) --112 + j*(98) --279 + j*(-98) -103 + j*(29) -115 + j*(13) -49 + j*(-102) -233 + j*(81) -189 + j*(-76) -192 + j*(52) --54 + j*(-86) --33 + j*(-18) --248 + j*(105) -76 + j*(177) -433 + j*(-158) --190 + j*(-6) --139 + j*(93) --57 + j*(-262) -165 + j*(-156) -305 + j*(-173) --5 + j*(323) -33 + j*(335) --156 + j*(-53) --235 + j*(111) --19 + j*(78) --34 + j*(-106) -254 + j*(62) --130 + j*(185) -5 + j*(-9) -53 + j*(-91) --107 + j*(357) --16 + j*(-24) -41 + j*(-177) --18 + j*(135) -102 + j*(223) --88 + j*(87) -173 + j*(251) --35 + j*(-85) --260 + j*(-141) -13 + j*(35) -235 + j*(136) -45 + j*(109) -57 + j*(-5) -59 + j*(-38) -148 + j*(78) -134 + j*(-247) --215 + j*(40) -243 + j*(-28) -42 + j*(-71) --59 + j*(-18) -63 + j*(-50) --286 + j*(-103) --140 + j*(-54) -43 + j*(-92) -117 + j*(-78) -58 + j*(-70) --2 + j*(-187) -33 + j*(1) --328 + j*(189) --151 + j*(-17) -70 + j*(56) --33 + j*(110) --56 + j*(-232) -139 + j*(211) -68 + j*(-8) --23 + j*(-332) --84 + j*(-69) --124 + j*(-66) -238 + j*(-9) -165 + j*(-138) -117 + j*(153) --3 + j*(-95) -252 + j*(-83) --146 + j*(81) --163 + j*(-2) -231 + j*(206) -103 + j*(-237) -14 + j*(-40) -187 + j*(175) --88 + j*(171) -66 + j*(202) -71 + j*(-172) --182 + j*(-47) --193 + j*(96) -158 + j*(197) --11 + j*(-202) --110 + j*(86) --76 + j*(-20) -23 + j*(-204) --110 + j*(228) -30 + j*(-39) -182 + j*(-27) -104 + j*(30) --421 + j*(55) --124 + j*(-89) -275 + j*(140) --114 + j*(65) -188 + j*(221) --515 + j*(152) --315 + j*(-170) -1 + j*(-225) -294 + j*(14) -202 + j*(6) -255 + j*(-163) --30 + j*(-192) --179 + j*(141) -148 + j*(-154) --74 + j*(-300) --235 + j*(18) -247 + j*(-79) -177 + j*(-129) --186 + j*(182) --50 + j*(-11) -356 + j*(-52) -148 + j*(-117) -136 + j*(99) -93 + j*(-328) --4 + j*(26) -7 + j*(-222) --58 + j*(-41) -236 + j*(106) --535 + j*(89) -356 + j*(320) --111 + j*(38) -58 + j*(-325) --165 + j*(103) --176 + j*(-89) --93 + j*(-48) --6 + j*(69) -110 + j*(-194) --19 + j*(1) -18 + j*(-311) -407 + j*(-1) -64 + j*(161) -142 + j*(-227) --356 + j*(-335) -195 + j*(366) --200 + j*(-170) -160 + j*(194) --43 + j*(-305) -168 + j*(-30) -221 + j*(146) --13 + j*(194) -366 + j*(-336) --265 + j*(107) --216 + j*(133) --73 + j*(124) --288 + j*(-79) --6 + j*(78) -359 + j*(126) --62 + j*(180) -205 + j*(-325) --21 + j*(-49) -54 + j*(-180) -77 + j*(-340) --77 + j*(-49) --87 + j*(166) -129 + j*(115) --167 + j*(25) -192 + j*(-13) -395 + j*(-304) -358 + j*(-41) -8 + j*(135) --91 + j*(-146) --103 + j*(-84) -136 + j*(98) --123 + j*(-60) -298 + j*(-141) --117 + j*(-283) -335 + j*(-21) -143 + j*(-44) --249 + j*(-75) -11 + j*(47) --146 + j*(-163) -185 + j*(232) -313 + j*(59) --227 + j*(-141) --214 + j*(-50) --64 + j*(143) -73 + j*(-165) -185 + j*(-30) -55 + j*(48) --152 + j*(-82) --35 + j*(-16) -49 + j*(-21) -4 + j*(313) -279 + j*(42) -48 + j*(-219) -40 + j*(37) --71 + j*(99) --75 + j*(-37) -11 + j*(-197) -118 + j*(40) --59 + j*(45) --106 + j*(79) -84 + j*(-100) --6 + j*(-39) --144 + j*(418) -52 + j*(351) -187 + j*(264) --26 + j*(25) --1 + j*(-44) --93 + j*(515) -63 + j*(-93) -296 + j*(78) --311 + j*(363) -4 + j*(-178) -63 + j*(265) --204 + j*(-132) -59 + j*(-104) --294 + j*(8) --167 + j*(76) --74 + j*(288) -105 + j*(-91) -105 + j*(21) -19 + j*(-169) -132 + j*(-124) -83 + j*(43) --302 + j*(-35) -155 + j*(206) -151 + j*(100) --242 + j*(188) -1 + j*(269) --30 + j*(-129) -387 + j*(-134) -135 + j*(89) -15 + j*(-282) -130 + j*(-124) -387 + j*(10) -136 + j*(74) --83 + j*(-74) --450 + j*(-119) --84 + j*(-28) --62 + j*(161) --76 + j*(-78) -75 + j*(-597) -273 + j*(80) --9 + j*(109) -4 + j*(62) -106 + j*(62) -105 + j*(199) --132 + j*(158) --21 + j*(5) --142 + j*(98) --282 + j*(170) -180 + j*(131) -211 + j*(-172) --155 + j*(192) --393 + j*(-5) --84 + j*(-328) --30 + j*(-112) --71 + j*(-198) -120 + j*(-38) --223 + j*(-73) --11 + j*(196) -170 + j*(76) --129 + j*(67) --121 + j*(-35) --66 + j*(103) --183 + j*(148) --215 + j*(-71) --158 + j*(-179) --211 + j*(13) --78 + j*(201) -245 + j*(132) --139 + j*(-11) --58 + j*(204) --103 + j*(-175) --12 + j*(73) --52 + j*(-126) -29 + j*(40) -67 + j*(-36) -18 + j*(-4) -15 + j*(-45) -268 + j*(-138) -62 + j*(25) --344 + j*(-20) -16 + j*(93) --122 + j*(119) --44 + j*(-205) -137 + j*(-150) -197 + j*(-11) -56 + j*(-64) -25 + j*(-168) -112 + j*(141) --144 + j*(29) --170 + j*(-252) --190 + j*(-37) --8 + j*(-127) --10 + j*(247) -193 + j*(-303) --122 + j*(-218) -165 + j*(-90) -28 + j*(-100) -31 + j*(19) --96 + j*(-121) --98 + j*(30) --281 + j*(-203) -250 + j*(-42) --244 + j*(109) --47 + j*(-231) -16 + j*(-291) -40 + j*(-218) --300 + j*(34) --152 + j*(173) --74 + j*(73) --23 + j*(-93) --45 + j*(-342) -24 + j*(-52) --193 + j*(183) --151 + j*(-307) --26 + j*(24) -207 + j*(-115) --58 + j*(139) --33 + j*(-112) --409 + j*(149) --1 + j*(-136) --288 + j*(-105) --30 + j*(-198) -187 + j*(39) -71 + j*(33) --371 + j*(64) --27 + j*(-169) -40 + j*(4) --234 + j*(72) --243 + j*(-18) -29 + j*(71) -189 + j*(-243) --201 + j*(-335) --214 + j*(-97) --161 + j*(185) --247 + j*(45) --260 + j*(-303) --206 + j*(245) --127 + j*(12) -49 + j*(156) --52 + j*(-3) -193 + j*(69) -203 + j*(62) -111 + j*(-100) --105 + j*(-18) -25 + j*(-121) --134 + j*(104) --275 + j*(233) -100 + j*(-326) --230 + j*(-73) -139 + j*(-256) -300 + j*(23) --189 + j*(-491) -137 + j*(-88) -133 + j*(-263) --106 + j*(-373) --18 + j*(-103) --98 + j*(223) --4 + j*(-18) -6 + j*(266) -60 + j*(-30) --188 + j*(-150) --118 + j*(40) --140 + j*(-16) -88 + j*(59) --22 + j*(-28) -110 + j*(-66) -160 + j*(-157) -139 + j*(31) -19 + j*(-97) -69 + j*(101) --49 + j*(172) -245 + j*(-80) -14 + j*(274) --71 + j*(1) --33 + j*(29) --208 + j*(66) -184 + j*(227) --239 + j*(-216) -127 + j*(-18) -469 + j*(177) --91 + j*(263) -4 + j*(46) --212 + j*(102) -25 + j*(-23) -153 + j*(10) --97 + j*(-8) --236 + j*(-30) --46 + j*(-418) --104 + j*(288) -78 + j*(-39) -136 + j*(1) -43 + j*(-76) -34 + j*(-223) -110 + j*(-4) -146 + j*(-64) --5 + j*(45) -89 + j*(44) --12 + j*(-76) --5 + j*(-25) -20 + j*(243) -47 + j*(-218) --81 + j*(71) --73 + j*(187) -314 + j*(94) --119 + j*(-69) -136 + j*(88) -158 + j*(75) --196 + j*(-190) --5 + j*(-135) -134 + j*(228) --108 + j*(-257) --16 + j*(414) --16 + j*(96) -151 + j*(163) -93 + j*(4) --204 + j*(-71) --107 + j*(213) -187 + j*(26) --30 + j*(242) -89 + j*(-8) -4 + j*(-206) --54 + j*(-242) -110 + j*(-37) --175 + j*(-238) --148 + j*(15) -208 + j*(-152) --28 + j*(-235) --183 + j*(-280) -189 + j*(-124) --19 + j*(8) --250 + j*(-168) --24 + j*(-89) --247 + j*(140) -216 + j*(385) -88 + j*(-119) -356 + j*(-173) -4 + j*(145) --193 + j*(-115) -109 + j*(-45) -203 + j*(172) --103 + j*(337) --80 + j*(187) --129 + j*(179) -158 + j*(-235) --52 + j*(-272) --91 + j*(327) --25 + j*(117) --143 + j*(-141) -92 + j*(310) -129 + j*(33) --202 + j*(159) -86 + j*(43) --43 + j*(69) --130 + j*(-140) --139 + j*(371) --1 + j*(92) --301 + j*(-141) -170 + j*(83) -6 + j*(-224) --183 + j*(132) --187 + j*(74) -141 + j*(-238) --102 + j*(346) --230 + j*(298) -71 + j*(280) --360 + j*(311) --85 + j*(173) -117 + j*(-69) -23 + j*(314) --179 + j*(234) -95 + j*(8) -18 + j*(-133) --137 + j*(-108) -115 + j*(122) --23 + j*(-101) -18 + j*(2) -96 + j*(-134) -21 + j*(3) -373 + j*(-148) -162 + j*(41) -240 + j*(244) --114 + j*(192) -86 + j*(-23) --55 + j*(67) --188 + j*(163) --23 + j*(10) -18 + j*(-76) --27 + j*(21) -163 + j*(198) --44 + j*(33) -70 + j*(66) --132 + j*(356) --43 + j*(-99) --134 + j*(165) -225 + j*(-81) --55 + j*(-30) -143 + j*(88) -64 + j*(-105) --44 + j*(-93) --69 + j*(-28) --184 + j*(-154) --315 + j*(184) -49 + j*(-148) --220 + j*(91) --91 + j*(-29) --177 + j*(-166) -35 + j*(86) --190 + j*(-197) --281 + j*(-106) --211 + j*(-90) --185 + j*(27) -50 + j*(298) -71 + j*(-78) -268 + j*(-33) -79 + j*(-139) -218 + j*(125) -400 + j*(190) --83 + j*(17) --129 + j*(385) --5 + j*(-299) --202 + j*(-363) -233 + j*(24) -13 + j*(-80) --256 + j*(-156) -194 + j*(-125) -233 + j*(104) --206 + j*(145) --181 + j*(137) --342 + j*(253) -91 + j*(13) --117 + j*(164) --138 + j*(58) -227 + j*(-179) --38 + j*(42) --46 + j*(-65) -98 + j*(302) --18 + j*(167) -135 + j*(136) -111 + j*(16) --107 + j*(-140) -69 + j*(-180) -69 + j*(-49) --100 + j*(190) --161 + j*(302) --57 + j*(261) -78 + j*(-50) -62 + j*(45) -298 + j*(24) -65 + j*(288) --132 + j*(4) -186 + j*(4) -53 + j*(84) --94 + j*(177) -258 + j*(-5) -82 + j*(-281) -282 + j*(295) -119 + j*(-278) --65 + j*(-95) --216 + j*(-46) -116 + j*(105) -13 + j*(287) -105 + j*(165) -221 + j*(-129) -27 + j*(115) --284 + j*(5) --20 + j*(190) -39 + j*(128) --301 + j*(-53) --198 + j*(-95) --39 + j*(129) --34 + j*(-30) --25 + j*(280) -134 + j*(176) --54 + j*(-99) -64 + j*(-139) --147 + j*(191) -77 + j*(-8) --140 + j*(1) -29 + j*(6) --252 + j*(-90) -66 + j*(-373) --273 + j*(177) --53 + j*(-73) -426 + j*(209) -303 + j*(-223) -230 + j*(78) --146 + j*(-151) -32 + j*(169) -408 + j*(48) -149 + j*(54) --18 + j*(-1) -320 + j*(122) --23 + j*(28) -89 + j*(-202) -33 + j*(-117) -274 + j*(-25) -23 + j*(-18) --88 + j*(-291) --51 + j*(407) --50 + j*(18) --4 + j*(-36) -115 + j*(124) --13 + j*(150) -223 + j*(-66) --48 + j*(108) --82 + j*(-92) -40 + j*(219) --216 + j*(148) --187 + j*(-291) --45 + j*(56) -185 + j*(47) -94 + j*(-248) --107 + j*(-1) --199 + j*(-47) -20 + j*(60) -117 + j*(141) --151 + j*(-326) -51 + j*(-210) -121 + j*(-66) --40 + j*(-173) --83 + j*(-199) --54 + j*(-74) -83 + j*(-98) -243 + j*(170) -217 + j*(-255) -242 + j*(-443) --148 + j*(-34) -42 + j*(201) -29 + j*(-47) --98 + j*(-1) -45 + j*(141) --148 + j*(-74) -161 + j*(-137) -116 + j*(169) -49 + j*(-519) -9 + j*(-118) -144 + j*(169) --106 + j*(77) --124 + j*(-10) --298 + j*(303) -268 + j*(-8) -44 + j*(-12) -165 + j*(-390) --98 + j*(-107) -199 + j*(197) -194 + j*(49) --206 + j*(412) -68 + j*(-216) -274 + j*(139) --237 + j*(60) -85 + j*(285) -4 + j*(-130) -168 + j*(-20) -284 + j*(175) -316 + j*(-301) -62 + j*(148) -54 + j*(-270) -95 + j*(266) --95 + j*(-28) --46 + j*(29) --254 + j*(-30) --159 + j*(117) --9 + j*(-117) --64 + j*(-76) -59 + j*(19) --45 + j*(-144) --358 + j*(-110) --302 + j*(218) -140 + j*(335) -233 + j*(12) -386 + j*(96) --37 + j*(-218) --187 + j*(-46) -16 + j*(290) -59 + j*(18) -158 + j*(-102) -104 + j*(-3) --23 + j*(204) -131 + j*(161) -105 + j*(339) --226 + j*(-220) --144 + j*(202) --95 + j*(-191) --44 + j*(49) -69 + j*(-114) --105 + j*(221) -12 + j*(58) -264 + j*(-68) --21 + j*(88) --357 + j*(15) --122 + j*(-136) --35 + j*(129) -139 + j*(-16) --175 + j*(-110) -24 + j*(67) -17 + j*(56) --100 + j*(-48) --75 + j*(-260) --28 + j*(-51) -52 + j*(-117) -445 + j*(41) -35 + j*(159) --68 + j*(112) --208 + j*(158) --182 + j*(-253) --3 + j*(-115) --30 + j*(371) -8 + j*(30) --223 + j*(-93) -274 + j*(57) --313 + j*(-148) -244 + j*(195) -10 + j*(-305) -296 + j*(88) -7 + j*(87) --40 + j*(91) --315 + j*(-76) --16 + j*(88) --83 + j*(-124) --98 + j*(-20) --94 + j*(-92) --143 + j*(-262) --87 + j*(49) -252 + j*(-49) --119 + j*(354) -134 + j*(46) --167 + j*(-270) --130 + j*(-144) -103 + j*(151) --87 + j*(243) -70 + j*(132) --128 + j*(2) -58 + j*(114) -215 + j*(14) --81 + j*(183) -37 + j*(65) --151 + j*(38) --92 + j*(75) --240 + j*(-64) --23 + j*(-105) --359 + j*(-221) --107 + j*(18) -88 + j*(-301) --308 + j*(542) --77 + j*(-313) -221 + j*(-117) --18 + j*(-79) -118 + j*(-240) --389 + j*(-11) -57 + j*(0) --142 + j*(-67) --115 + j*(-76) -39 + j*(-61) -182 + j*(0) --65 + j*(46) -57 + j*(-47) --304 + j*(33) --430 + j*(489) --425 + j*(47) -261 + j*(597) --67 + j*(314) --337 + j*(167) --143 + j*(-90) --353 + j*(-21) --335 + j*(162) -605 + j*(390) --31 + j*(-196) --340 + j*(-206) --275 + j*(-161) --332 + j*(120) -422 + j*(202) -316 + j*(192) --141 + j*(535) --296 + j*(-251) -209 + j*(-497) --286 + j*(-75) -165 + j*(470) --82 + j*(273) -99 + j*(267) --262 + j*(188) --15 + j*(172) --30 + j*(403) -212 + j*(272) --204 + j*(-431) --351 + j*(-269) -589 + j*(204) -311 + j*(-122) -391 + j*(-222) --371 + j*(286) --566 + j*(-589) -202 + j*(-261) --151 + j*(-124) -474 + j*(-434) -272 + j*(-49) -359 + j*(75) -129 + j*(-83) --320 + j*(-96) -140 + j*(-76) --211 + j*(-550) -305 + j*(417) --412 + j*(64) -226 + j*(-547) -407 + j*(-380) --83 + j*(-97) -396 + j*(-173) -255 + j*(-368) -213 + j*(-57) -313 + j*(110) -42 + j*(158) --93 + j*(-151) --267 + j*(12) --50 + j*(119) --161 + j*(-238) --6 + j*(-322) --392 + j*(-337) -472 + j*(-371) -142 + j*(421) --317 + j*(400) -447 + j*(-417) -487 + j*(-246) --265 + j*(420) --237 + j*(279) --163 + j*(188) --423 + j*(341) --38 + j*(-321) -492 + j*(101) --297 + j*(-282) --43 + j*(210) -247 + j*(262) -219 + j*(253) -446 + j*(250) --492 + j*(-336) -272 + j*(-373) -289 + j*(241) --71 + j*(-12) --334 + j*(684) --156 + j*(294) -219 + j*(168) -222 + j*(391) --127 + j*(585) -458 + j*(-467) -400 + j*(-296) --229 + j*(1) --195 + j*(130) --42 + j*(-72) --548 + j*(46) -168 + j*(17) --109 + j*(307) -274 + j*(-205) -181 + j*(-606) -23 + j*(216) --359 + j*(13) -91 + j*(288) --216 + j*(141) --315 + j*(-303) -165 + j*(450) --474 + j*(64) -450 + j*(-318) --443 + j*(348) -131 + j*(450) -259 + j*(401) --464 + j*(-486) -74 + j*(-565) --122 + j*(-119) -512 + j*(-184) --305 + j*(201) -199 + j*(-392) -158 + j*(-424) -156 + j*(43) --610 + j*(289) -172 + j*(-296) -47 + j*(297) --458 + j*(-441) -222 + j*(-376) --399 + j*(8) --208 + j*(371) --65 + j*(-204) --322 + j*(663) --438 + j*(-144) -144 + j*(123) -97 + j*(363) -164 + j*(-170) --237 + j*(167) -117 + j*(55) -342 + j*(-199) --254 + j*(226) --356 + j*(474) --164 + j*(171) -393 + j*(-431) --197 + j*(-47) -192 + j*(179) -183 + j*(-356) -377 + j*(-268) -465 + j*(407) --193 + j*(-66) --267 + j*(-235) -607 + j*(416) --198 + j*(310) -403 + j*(542) -182 + j*(-26) --594 + j*(-251) --167 + j*(-284) --265 + j*(667) -171 + j*(-404) -122 + j*(-467) --266 + j*(57) --361 + j*(-285) -348 + j*(23) --206 + j*(-553) --160 + j*(309) -491 + j*(283) --422 + j*(-171) --202 + j*(-250) --229 + j*(99) -183 + j*(95) -134 + j*(-175) -172 + j*(-517) -147 + j*(385) --446 + j*(392) -228 + j*(106) -90 + j*(-122) --284 + j*(-69) --255 + j*(-495) -99 + j*(-112) --347 + j*(-191) -355 + j*(173) --342 + j*(175) -407 + j*(-28) -223 + j*(-71) --313 + j*(26) -156 + j*(-120) -392 + j*(-379) --321 + j*(-26) --399 + j*(160) -187 + j*(228) --249 + j*(-415) -404 + j*(399) -198 + j*(253) -438 + j*(82) -479 + j*(237) -363 + j*(318) -576 + j*(-229) --667 + j*(-161) -300 + j*(-527) -92 + j*(596) --7 + j*(-363) --397 + j*(414) -142 + j*(220) -535 + j*(395) -306 + j*(418) --162 + j*(-406) -354 + j*(-330) --219 + j*(162) --331 + j*(-506) -496 + j*(225) -133 + j*(115) -214 + j*(218) -197 + j*(-316) -587 + j*(9) --30 + j*(397) --547 + j*(-593) -352 + j*(-108) --219 + j*(142) --383 + j*(286) --216 + j*(-329) -390 + j*(276) --157 + j*(-122) -236 + j*(122) -31 + j*(-37) -174 + j*(-285) -253 + j*(-253) -427 + j*(-403) --315 + j*(345) --428 + j*(-682) -15 + j*(-400) --339 + j*(496) --588 + j*(91) -229 + j*(-165) -529 + j*(296) -553 + j*(346) --144 + j*(66) --397 + j*(452) -445 + j*(406) --112 + j*(-163) -301 + j*(253) -296 + j*(274) -354 + j*(-94) --457 + j*(-530) --373 + j*(-168) --270 + j*(-178) --407 + j*(-224) -3 + j*(-22) -177 + j*(288) --476 + j*(31) --296 + j*(232) --331 + j*(-110) -429 + j*(-240) -385 + j*(-395) --89 + j*(326) -369 + j*(243) --419 + j*(30) -117 + j*(-298) --83 + j*(388) -427 + j*(119) --233 + j*(-222) --437 + j*(509) --329 + j*(-51) -184 + j*(238) -383 + j*(-150) -398 + j*(204) --277 + j*(-255) --166 + j*(105) -409 + j*(-567) --312 + j*(-180) -85 + j*(-119) --353 + j*(52) --416 + j*(-530) --59 + j*(-94) --454 + j*(-723) -321 + j*(148) --545 + j*(-355) --286 + j*(-40) -398 + j*(-600) -144 + j*(-344) -199 + j*(-606) --42 + j*(290) --328 + j*(-112) --199 + j*(-245) -303 + j*(-335) --484 + j*(-413) --314 + j*(98) --100 + j*(-88) --328 + j*(383) --117 + j*(33) -491 + j*(-299) -320 + j*(426) -124 + j*(320) --184 + j*(223) --165 + j*(-230) -280 + j*(-183) -67 + j*(-808) -104 + j*(177) -260 + j*(-230) -454 + j*(-49) -145 + j*(-433) --284 + j*(-306) -336 + j*(-199) --338 + j*(-395) -168 + j*(-86) --537 + j*(-232) --396 + j*(-558) -587 + j*(-207) -155 + j*(-412) --122 + j*(185) --648 + j*(-65) --167 + j*(-233) --371 + j*(308) --449 + j*(-25) -156 + j*(233) --207 + j*(243) --474 + j*(313) -325 + j*(6) --183 + j*(269) --344 + j*(-54) --98 + j*(325) -382 + j*(197) --304 + j*(-89) -100 + j*(-390) --471 + j*(-12) -237 + j*(255) -247 + j*(-138) --98 + j*(-78) -63 + j*(199) --258 + j*(-231) --470 + j*(-422) --224 + j*(378) -629 + j*(1) --255 + j*(-604) --100 + j*(478) --19 + j*(430) -663 + j*(213) -222 + j*(181) --127 + j*(270) -351 + j*(-373) -308 + j*(192) --149 + j*(240) -80 + j*(-377) -120 + j*(-112) --96 + j*(-182) --8 + j*(-73) -477 + j*(-154) --419 + j*(274) --496 + j*(256) --240 + j*(410) -150 + j*(-351) --243 + j*(-137) --11 + j*(-345) -100 + j*(197) -67 + j*(52) -247 + j*(276) -106 + j*(404) --426 + j*(-358) -161 + j*(-528) -211 + j*(233) --408 + j*(180) -334 + j*(464) -469 + j*(-114) -278 + j*(178) -86 + j*(-257) -78 + j*(-322) -457 + j*(-159) --275 + j*(328) --508 + j*(-10) -209 + j*(89) --301 + j*(291) --247 + j*(-146) -259 + j*(177) -83 + j*(-61) --369 + j*(-315) --206 + j*(-272) --194 + j*(53) -344 + j*(291) -242 + j*(-343) -433 + j*(-74) -424 + j*(423) --332 + j*(160) --345 + j*(675) -209 + j*(-36) --152 + j*(-247) --177 + j*(434) -312 + j*(317) -197 + j*(-103) --355 + j*(112) --69 + j*(-194) -400 + j*(118) -151 + j*(506) -386 + j*(-337) -451 + j*(228) -40 + j*(-25) -48 + j*(-194) --218 + j*(-320) -207 + j*(-124) --117 + j*(-141) -343 + j*(-224) -308 + j*(291) --247 + j*(-361) -511 + j*(32) -228 + j*(91) -380 + j*(302) -324 + j*(-119) --413 + j*(463) -292 + j*(281) --201 + j*(-165) --303 + j*(-211) --471 + j*(418) --69 + j*(-121) --607 + j*(274) -141 + j*(342) --339 + j*(-220) --51 + j*(-165) -229 + j*(-407) --151 + j*(263) --238 + j*(-291) -316 + j*(-284) -279 + j*(-5) -530 + j*(231) -362 + j*(-301) --351 + j*(88) --110 + j*(-561) -112 + j*(460) --511 + j*(-83) -465 + j*(-271) -302 + j*(-204) -164 + j*(355) --293 + j*(-134) -190 + j*(-144) -306 + j*(343) -368 + j*(298) -53 + j*(-6) --45 + j*(180) --273 + j*(359) --361 + j*(58) --361 + j*(-168) --212 + j*(-321) --178 + j*(13) -186 + j*(-363) --138 + j*(276) -149 + j*(-330) --303 + j*(291) -427 + j*(-233) -410 + j*(147) --484 + j*(243) -57 + j*(-330) -357 + j*(-601) -107 + j*(86) -402 + j*(-378) --295 + j*(-273) --211 + j*(-189) -264 + j*(360) -525 + j*(78) -414 + j*(161) --354 + j*(-292) -457 + j*(262) --247 + j*(284) -316 + j*(-690) -285 + j*(-289) -109 + j*(-199) --414 + j*(-325) --316 + j*(151) --11 + j*(278) -296 + j*(57) -403 + j*(187) -196 + j*(129) --380 + j*(-382) --358 + j*(432) -311 + j*(-158) --141 + j*(-752) --210 + j*(223) -181 + j*(-170) --144 + j*(479) -42 + j*(337) --118 + j*(-448) -222 + j*(-74) -631 + j*(-293) -339 + j*(-683) --165 + j*(141) -388 + j*(-554) --211 + j*(358) --309 + j*(110) --313 + j*(130) -223 + j*(560) -415 + j*(496) -11 + j*(344) -634 + j*(-202) -226 + j*(-28) --185 + j*(363) --289 + j*(107) -43 + j*(301) -91 + j*(-283) -76 + j*(-579) --298 + j*(95) -31 + j*(84) --288 + j*(252) -194 + j*(413) -264 + j*(-355) -165 + j*(-302) --120 + j*(101) -344 + j*(-684) --288 + j*(52) --290 + j*(-463) --135 + j*(286) --445 + j*(-125) --263 + j*(97) --277 + j*(-421) -302 + j*(-375) -455 + j*(412) --128 + j*(63) -118 + j*(107) --360 + j*(407) -54 + j*(366) --74 + j*(-502) -234 + j*(242) -572 + j*(-114) -197 + j*(-351) -518 + j*(128) -477 + j*(462) --64 + j*(393) --113 + j*(-435) -303 + j*(-301) --221 + j*(146) --116 + j*(-151) --352 + j*(-286) --298 + j*(-105) -153 + j*(-247) -539 + j*(7) -360 + j*(144) -110 + j*(74) -328 + j*(28) --337 + j*(424) -129 + j*(-260) -549 + j*(41) --368 + j*(378) --253 + j*(-668) -263 + j*(180) -253 + j*(-273) --412 + j*(212) --180 + j*(207) --329 + j*(-180) -154 + j*(-82) --102 + j*(197) --356 + j*(107) --89 + j*(-513) --393 + j*(41) -344 + j*(403) -245 + j*(286) --390 + j*(146) -184 + j*(-487) -132 + j*(-408) --330 + j*(441) --28 + j*(579) -197 + j*(-210) --52 + j*(-171) -317 + j*(201) --162 + j*(-148) -111 + j*(-285) --148 + j*(177) --291 + j*(210) --358 + j*(-169) -421 + j*(-378) --173 + j*(52) -19 + j*(-194) -211 + j*(62) --416 + j*(202) --296 + j*(194) --357 + j*(72) --214 + j*(49) -289 + j*(400) --182 + j*(349) --583 + j*(-578) --322 + j*(232) --136 + j*(179) -276 + j*(397) --436 + j*(24) --224 + j*(-35) -74 + j*(110) --414 + j*(-103) --369 + j*(513) --141 + j*(-160) -309 + j*(346) -276 + j*(763) --186 + j*(401) -137 + j*(202) -179 + j*(272) --358 + j*(217) -109 + j*(330) --497 + j*(70) --352 + j*(288) -957 + j*(428) -136 + j*(149) --426 + j*(-522) -91 + j*(52) --378 + j*(150) --367 + j*(416) -130 + j*(123) --260 + j*(361) --31 + j*(-247) -346 + j*(-375) -166 + j*(-52) -158 + j*(-178) --497 + j*(201) -376 + j*(-266) --416 + j*(258) --198 + j*(175) --107 + j*(-139) --255 + j*(77) --380 + j*(267) --342 + j*(277) --279 + j*(-194) -217 + j*(9) -65 + j*(-134) --23 + j*(-395) -195 + j*(262) -86 + j*(-10) --37 + j*(278) --40 + j*(-135) -6 + j*(-1) -144 + j*(163) --16 + j*(-21) --5 + j*(147) --47 + j*(-260) --321 + j*(172) -238 + j*(-30) -216 + j*(81) -11 + j*(-53) --47 + j*(-23) -93 + j*(-51) --1 + j*(-8) --76 + j*(-121) --240 + j*(0) --38 + j*(-183) -0 + j*(163) -234 + j*(-31) --15 + j*(244) -76 + j*(-4) --153 + j*(257) -173 + j*(26) --37 + j*(-276) --131 + j*(206) -65 + j*(192) -278 + j*(-243) --161 + j*(-1) -44 + j*(-173) -167 + j*(245) --102 + j*(122) --47 + j*(-253) --21 + j*(-165) --1 + j*(57) -10 + j*(-13) -48 + j*(188) --45 + j*(-52) --17 + j*(-233) -32 + j*(-101) --295 + j*(-116) -388 + j*(128) --134 + j*(-117) --81 + j*(-160) --45 + j*(-393) -72 + j*(-60) --24 + j*(-247) -208 + j*(-424) -280 + j*(-19) --87 + j*(276) -23 + j*(70) -88 + j*(-285) -1 + j*(-189) -121 + j*(-41) --55 + j*(-153) --192 + j*(147) -98 + j*(-22) -0 + j*(218) --347 + j*(138) --95 + j*(-165) -214 + j*(-88) --113 + j*(-315) --131 + j*(390) --264 + j*(144) -114 + j*(-233) --54 + j*(-50) --342 + j*(124) --173 + j*(-27) -140 + j*(-115) -48 + j*(361) --327 + j*(187) --40 + j*(-163) --104 + j*(229) -144 + j*(-105) --83 + j*(-214) -183 + j*(117) --150 + j*(75) -160 + j*(-52) --6 + j*(-65) -209 + j*(132) --195 + j*(275) -75 + j*(-323) --33 + j*(-221) -92 + j*(-206) -8 + j*(-38) --83 + j*(-167) -68 + j*(198) -31 + j*(13) --310 + j*(318) -105 + j*(175) -5 + j*(-67) -42 + j*(-11) -107 + j*(29) -79 + j*(-83) --68 + j*(-226) -366 + j*(92) --146 + j*(172) -74 + j*(386) -160 + j*(-37) -327 + j*(-145) --189 + j*(208) --25 + j*(-168) -93 + j*(-51) -15 + j*(202) -4 + j*(2) -37 + j*(152) --97 + j*(-64) -276 + j*(257) --67 + j*(-88) --58 + j*(-4) --297 + j*(242) --194 + j*(-285) --26 + j*(139) --220 + j*(271) -27 + j*(-36) --277 + j*(98) -182 + j*(-327) -314 + j*(211) --52 + j*(-117) --92 + j*(64) --197 + j*(-198) --291 + j*(16) -45 + j*(100) -7 + j*(-226) --6 + j*(-90) --440 + j*(110) --20 + j*(144) -296 + j*(-84) --49 + j*(29) --97 + j*(416) --202 + j*(-2) -31 + j*(-51) --156 + j*(-209) --198 + j*(-40) -66 + j*(82) --215 + j*(378) -414 + j*(23) --291 + j*(122) -221 + j*(-47) --374 + j*(33) -348 + j*(-216) -187 + j*(70) -129 + j*(-145) --108 + j*(-35) --100 + j*(-327) -228 + j*(-83) -334 + j*(107) --380 + j*(-332) --64 + j*(93) -177 + j*(-193) --50 + j*(-9) --325 + j*(152) --71 + j*(111) -291 + j*(-116) --158 + j*(229) --150 + j*(-164) -36 + j*(126) -8 + j*(-73) -190 + j*(-161) --25 + j*(-20) -130 + j*(99) -35 + j*(276) -242 + j*(171) --145 + j*(-106) -103 + j*(-179) -127 + j*(-1) --112 + j*(-151) --141 + j*(308) -199 + j*(-22) -23 + j*(156) --23 + j*(-225) --168 + j*(37) --245 + j*(83) -145 + j*(40) --308 + j*(-13) -39 + j*(7) -16 + j*(-214) -87 + j*(-40) --126 + j*(-33) -371 + j*(313) -80 + j*(-34) -8 + j*(175) --110 + j*(368) --66 + j*(130) -124 + j*(-55) --166 + j*(-139) -119 + j*(126) --124 + j*(245) --150 + j*(110) -161 + j*(-21) -52 + j*(-105) --98 + j*(27) --139 + j*(125) -38 + j*(76) --90 + j*(259) --3 + j*(23) -31 + j*(84) -292 + j*(-22) --146 + j*(505) -293 + j*(71) --9 + j*(198) -9 + j*(15) --60 + j*(-96) --231 + j*(241) --232 + j*(-240) -211 + j*(-120) --145 + j*(54) -3 + j*(16) --204 + j*(-413) --373 + j*(-87) --5 + j*(128) --222 + j*(-5) --42 + j*(-223) --224 + j*(33) --10 + j*(-8) --134 + j*(25) --187 + j*(351) -109 + j*(-105) -114 + j*(-36) --226 + j*(84) --168 + j*(-105) --91 + j*(-60) -55 + j*(-227) --25 + j*(-95) --35 + j*(325) -59 + j*(-122) -81 + j*(-134) --172 + j*(117) --4 + j*(141) -30 + j*(-124) --381 + j*(-111) --119 + j*(-175) -103 + j*(-36) --96 + j*(-64) -197 + j*(-59) -52 + j*(-100) --151 + j*(125) --132 + j*(-57) --35 + j*(-74) -52 + j*(-267) -139 + j*(4) --177 + j*(177) --141 + j*(-110) --64 + j*(372) --204 + j*(-33) -113 + j*(187) --123 + j*(91) -177 + j*(-75) -56 + j*(-164) --342 + j*(178) --83 + j*(124) -71 + j*(-26) --179 + j*(76) --7 + j*(-199) --92 + j*(94) -67 + j*(-88) -62 + j*(197) -144 + j*(223) --164 + j*(25) -148 + j*(-99) -176 + j*(-33) -96 + j*(-22) -4 + j*(-28) -8 + j*(-88) --38 + j*(69) -20 + j*(27) --151 + j*(-105) -46 + j*(279) --182 + j*(-129) -187 + j*(-45) -125 + j*(41) --105 + j*(260) -139 + j*(-175) -197 + j*(62) --47 + j*(-6) -8 + j*(-264) -145 + j*(-122) --71 + j*(-253) --63 + j*(233) -121 + j*(-4) --58 + j*(111) -358 + j*(151) --23 + j*(-28) -11 + j*(-8) -11 + j*(26) --92 + j*(-46) --100 + j*(336) --50 + j*(31) --165 + j*(-91) -116 + j*(-206) -65 + j*(272) --177 + j*(163) --134 + j*(44) -194 + j*(84) -214 + j*(-51) --225 + j*(210) -88 + j*(158) -120 + j*(-69) -111 + j*(115) -139 + j*(205) -329 + j*(-174) -47 + j*(82) --327 + j*(-317) -37 + j*(154) -84 + j*(14) -84 + j*(-11) -221 + j*(155) --364 + j*(194) -113 + j*(43) -4 + j*(21) --107 + j*(-91) --89 + j*(26) --249 + j*(-27) -23 + j*(132) -127 + j*(-84) --12 + j*(-115) --71 + j*(-11) --30 + j*(-1) --172 + j*(138) -335 + j*(131) --389 + j*(-301) --227 + j*(-21) -31 + j*(-216) --5 + j*(-132) --144 + j*(-299) --165 + j*(228) -3 + j*(-140) --32 + j*(64) --133 + j*(62) --59 + j*(-167) --209 + j*(-176) -313 + j*(-33) --28 + j*(137) -184 + j*(219) --16 + j*(294) --196 + j*(-70) --86 + j*(38) --75 + j*(-91) -356 + j*(226) --60 + j*(390) -22 + j*(-121) -90 + j*(76) --141 + j*(-10) -87 + j*(57) --245 + j*(-4) -88 + j*(-81) --40 + j*(148) --1 + j*(209) -216 + j*(24) -26 + j*(13) --249 + j*(45) -251 + j*(-110) --366 + j*(-232) -13 + j*(130) -17 + j*(271) --126 + j*(-201) --52 + j*(-122) -102 + j*(-264) -74 + j*(206) -317 + j*(-79) -122 + j*(13) -186 + j*(132) --86 + j*(-180) --253 + j*(-194) -86 + j*(-68) --88 + j*(-161) -159 + j*(-275) -146 + j*(-74) --85 + j*(-33) --16 + j*(-133) --136 + j*(-61) --112 + j*(-103) --156 + j*(57) -43 + j*(-80) -58 + j*(193) --187 + j*(-203) -197 + j*(191) -277 + j*(26) -4 + j*(-117) --81 + j*(182) --8 + j*(-11) -54 + j*(-61) --351 + j*(64) --178 + j*(-216) --4 + j*(-388) --141 + j*(91) --140 + j*(-93) -33 + j*(197) -63 + j*(-147) -17 + j*(132) -10 + j*(127) --253 + j*(192) --36 + j*(107) -125 + j*(-66) --131 + j*(-82) --250 + j*(-14) --285 + j*(5) -119 + j*(-23) -28 + j*(253) --49 + j*(330) -73 + j*(24) -82 + j*(40) -4 + j*(179) -44 + j*(-324) --77 + j*(64) --16 + j*(-161) -181 + j*(-55) --248 + j*(-226) --185 + j*(130) -108 + j*(110) --337 + j*(-95) -117 + j*(-192) --18 + j*(104) -185 + j*(204) --106 + j*(28) --400 + j*(57) --91 + j*(47) --243 + j*(-143) --141 + j*(37) -216 + j*(79) --63 + j*(23) -1 + j*(-54) --258 + j*(254) --26 + j*(-60) -203 + j*(132) -260 + j*(57) --13 + j*(209) -46 + j*(-156) -55 + j*(294) --322 + j*(-226) -101 + j*(118) -163 + j*(-56) -189 + j*(-47) -209 + j*(-12) -140 + j*(146) --81 + j*(282) --238 + j*(20) --152 + j*(180) --140 + j*(-190) -146 + j*(-109) --63 + j*(-105) -49 + j*(6) --37 + j*(-4) -25 + j*(-124) -21 + j*(-45) -214 + j*(209) -6 + j*(-68) --174 + j*(189) -79 + j*(-70) -103 + j*(167) --227 + j*(171) --139 + j*(-351) -245 + j*(-18) --17 + j*(325) --490 + j*(-99) -301 + j*(81) -218 + j*(-4) -32 + j*(-16) -274 + j*(-51) --122 + j*(21) -95 + j*(7) -295 + j*(-64) --18 + j*(245) --122 + j*(47) -86 + j*(7) -122 + j*(-269) -35 + j*(-125) -29 + j*(34) -187 + j*(53) --205 + j*(-129) --29 + j*(264) -93 + j*(-149) --36 + j*(-107) --225 + j*(255) -371 + j*(-177) --142 + j*(11) --230 + j*(217) --100 + j*(-18) -40 + j*(163) --57 + j*(-83) --293 + j*(316) --86 + j*(-52) -111 + j*(21) --91 + j*(-33) --121 + j*(-47) --133 + j*(-12) --7 + j*(124) --154 + j*(-30) --74 + j*(-225) -14 + j*(-54) --176 + j*(252) --217 + j*(-202) -65 + j*(-130) -144 + j*(192) -209 + j*(-108) -11 + j*(264) --10 + j*(-170) --9 + j*(-129) --90 + j*(-147) -108 + j*(44) --19 + j*(99) --256 + j*(53) -301 + j*(-249) --164 + j*(124) --231 + j*(-234) --64 + j*(-274) --40 + j*(28) -54 + j*(-162) -99 + j*(72) -78 + j*(135) --120 + j*(165) -123 + j*(-209) --23 + j*(306) --133 + j*(-216) --35 + j*(121) -260 + j*(264) -134 + j*(25) --32 + j*(255) --245 + j*(-106) --35 + j*(-74) -192 + j*(-317) --175 + j*(286) --25 + j*(-154) --146 + j*(29) -40 + j*(181) --10 + j*(119) --47 + j*(-151) -161 + j*(105) -205 + j*(-194) --270 + j*(28) --18 + j*(1) --131 + j*(125) -176 + j*(-149) -21 + j*(80) -13 + j*(-211) --273 + j*(123) --182 + j*(176) --247 + j*(87) -72 + j*(141) --78 + j*(-149) --96 + j*(158) --235 + j*(-231) --2 + j*(194) -44 + j*(192) --6 + j*(-80) -37 + j*(-110) --148 + j*(-328) --267 + j*(251) -168 + j*(175) -97 + j*(30) --54 + j*(-40) --168 + j*(89) --72 + j*(-33) --68 + j*(-249) --100 + j*(48) -64 + j*(-49) --161 + j*(150) -31 + j*(137) -27 + j*(-29) -243 + j*(28) --22 + j*(-22) -94 + j*(22) --238 + j*(-66) --6 + j*(-87) --109 + j*(99) -184 + j*(204) --250 + j*(-3) -263 + j*(-223) --428 + j*(-54) -155 + j*(-169) -43 + j*(-285) --182 + j*(-257) -71 + j*(-199) -37 + j*(-130) -51 + j*(41) --75 + j*(-66) --95 + j*(105) -33 + j*(-125) --195 + j*(-38) -281 + j*(-226) --16 + j*(-185) -85 + j*(64) --13 + j*(-259) -25 + j*(-330) -342 + j*(218) -91 + j*(331) --245 + j*(-42) --240 + j*(224) --66 + j*(-228) --37 + j*(182) -128 + j*(214) -109 + j*(129) --244 + j*(135) -237 + j*(178) --14 + j*(-62) --26 + j*(11) --275 + j*(-257) -99 + j*(-284) -97 + j*(501) --361 + j*(-166) --69 + j*(96) --25 + j*(-182) -227 + j*(94) -157 + j*(445) --29 + j*(-144) -368 + j*(-150) -40 + j*(-45) --46 + j*(143) -56 + j*(-343) --4 + j*(62) -272 + j*(-117) --291 + j*(83) --387 + j*(111) --93 + j*(-18) -250 + j*(-13) --193 + j*(48) -59 + j*(706) -264 + j*(228) -33 + j*(-315) -404 + j*(-147) --79 + j*(1) --296 + j*(-135) --250 + j*(-423) -36 + j*(27) -64 + j*(-75) --195 + j*(-198) --51 + j*(-132) --103 + j*(204) -261 + j*(-173) -44 + j*(-41) --77 + j*(55) --18 + j*(-163) --241 + j*(106) -76 + j*(-120) -346 + j*(323) --168 + j*(-142) -83 + j*(-60) -30 + j*(262) -250 + j*(-2) --146 + j*(-236) --66 + j*(-267) --28 + j*(-10) --58 + j*(-90) -139 + j*(-92) -143 + j*(105) --192 + j*(525) -119 + j*(158) -15 + j*(-111) -25 + j*(-11) --103 + j*(144) --283 + j*(-173) -356 + j*(-98) --53 + j*(274) --1 + j*(94) -204 + j*(91) -127 + j*(-239) --121 + j*(62) --2 + j*(145) -134 + j*(-30) --77 + j*(320) -148 + j*(27) --372 + j*(-130) -274 + j*(8) -71 + j*(-80) -333 + j*(-121) --292 + j*(-135) -205 + j*(479) --37 + j*(-227) -62 + j*(61) -83 + j*(-158) -279 + j*(-41) -31 + j*(132) --54 + j*(472) --214 + j*(261) -148 + j*(-199) -73 + j*(499) -78 + j*(-23) -108 + j*(-213) -25 + j*(-210) -12 + j*(315) --42 + j*(63) --86 + j*(119) -76 + j*(246) -211 + j*(-351) --42 + j*(-95) --47 + j*(156) -37 + j*(144) --249 + j*(-69) --274 + j*(-139) -110 + j*(-13) --269 + j*(21) -173 + j*(-42) -55 + j*(110) --130 + j*(-165) --187 + j*(-255) --53 + j*(-127) -262 + j*(-6) -16 + j*(28) --292 + j*(-63) --219 + j*(-310) --93 + j*(404) --34 + j*(60) -78 + j*(-91) --74 + j*(146) --162 + j*(-143) --127 + j*(64) -400 + j*(-46) --81 + j*(373) -408 + j*(-136) --45 + j*(13) --161 + j*(-119) -39 + j*(310) -50 + j*(-281) --64 + j*(4) -305 + j*(69) --59 + j*(45) --137 + j*(416) -56 + j*(-198) -273 + j*(-237) -141 + j*(173) -18 + j*(-60) --41 + j*(225) -236 + j*(297) -80 + j*(18) --388 + j*(277) -180 + j*(-110) --67 + j*(-74) --215 + j*(-148) -8 + j*(242) --293 + j*(-219) --88 + j*(81) -117 + j*(-18) -78 + j*(-66) --80 + j*(-532) -141 + j*(21) --211 + j*(-342) --204 + j*(-96) --131 + j*(-108) -124 + j*(-298) -43 + j*(-57) -13 + j*(220) -206 + j*(33) -43 + j*(-93) --8 + j*(-59) -300 + j*(-127) --181 + j*(218) -110 + j*(-66) -148 + j*(372) --188 + j*(66) -28 + j*(-363) --211 + j*(37) -110 + j*(22) --132 + j*(110) --122 + j*(-109) --124 + j*(241) --132 + j*(8) --109 + j*(-1) --186 + j*(-119) --202 + j*(-288) --29 + j*(143) -115 + j*(-307) --51 + j*(-297) --89 + j*(-169) -26 + j*(299) -66 + j*(76) --62 + j*(133) --110 + j*(-276) -410 + j*(-174) --315 + j*(-66) --5 + j*(165) -175 + j*(-115) --167 + j*(-226) --148 + j*(273) -197 + j*(-184) --124 + j*(159) -285 + j*(-25) -221 + j*(13) -102 + j*(-86) -56 + j*(183) --1 + j*(-25) -71 + j*(-21) --281 + j*(156) --62 + j*(40) --3 + j*(153) -159 + j*(323) --15 + j*(173) --105 + j*(-136) -1 + j*(25) -7 + j*(154) --380 + j*(-333) --211 + j*(293) -11 + j*(-76) --137 + j*(-161) -44 + j*(-180) -378 + j*(-2) -322 + j*(-284) -217 + j*(34) -107 + j*(161) --20 + j*(156) -36 + j*(-98) --142 + j*(11) -117 + j*(105) -51 + j*(-16) -253 + j*(-144) --33 + j*(-183) --190 + j*(-316) --55 + j*(207) --121 + j*(440) --301 + j*(-78) --73 + j*(-63) -95 + j*(-9) --110 + j*(196) -329 + j*(-70) --90 + j*(34) --246 + j*(177) --52 + j*(-62) -40 + j*(-156) -13 + j*(67) --311 + j*(129) -101 + j*(88) --107 + j*(107) --245 + j*(-196) --18 + j*(216) -126 + j*(161) --21 + j*(194) --64 + j*(-221) -40 + j*(-85) -107 + j*(168) -24 + j*(84) --122 + j*(15) --183 + j*(-73) -133 + j*(-38) --105 + j*(37) --154 + j*(35) -100 + j*(150) -500 + j*(-12) -115 + j*(4) -290 + j*(41) -243 + j*(-122) --17 + j*(-80) -49 + j*(-163) --144 + j*(-378) --375 + j*(-136) -35 + j*(-108) --19 + j*(-320) --138 + j*(-10) -169 + j*(-57) --212 + j*(114) -375 + j*(-63) --171 + j*(117) -205 + j*(-184) --233 + j*(77) -74 + j*(-168) --19 + j*(142) --77 + j*(124) --53 + j*(-18) -51 + j*(-360) --148 + j*(-2) -226 + j*(-23) -61 + j*(-165) --67 + j*(-58) -278 + j*(-44) -412 + j*(-89) --74 + j*(-80) --32 + j*(151) --106 + j*(226) -190 + j*(-121) --247 + j*(-198) -36 + j*(-45) --82 + j*(311) -115 + j*(1) --379 + j*(4) -172 + j*(38) --187 + j*(134) --156 + j*(-50) --126 + j*(-186) --20 + j*(-57) -312 + j*(-151) --218 + j*(180) --42 + j*(-283) --98 + j*(112) -145 + j*(57) -21 + j*(-140) -223 + j*(119) -71 + j*(-245) -134 + j*(243) --80 + j*(252) --33 + j*(-303) --5 + j*(84) --161 + j*(-120) --268 + j*(-303) --62 + j*(-187) --151 + j*(-25) -164 + j*(-359) --130 + j*(293) --35 + j*(-424) --359 + j*(368) -79 + j*(235) -344 + j*(-23) --98 + j*(-108) -157 + j*(221) --342 + j*(-91) -35 + j*(-46) --111 + j*(-6) -119 + j*(-21) --146 + j*(144) -167 + j*(36) --347 + j*(-155) -238 + j*(4) -37 + j*(249) --159 + j*(-104) --79 + j*(348) -58 + j*(199) --2 + j*(-211) -347 + j*(73) -28 + j*(-163) --150 + j*(143) --34 + j*(-91) --53 + j*(390) --163 + j*(135) --274 + j*(-153) -69 + j*(194) -131 + j*(-263) --412 + j*(177) --86 + j*(-347) -52 + j*(-134) -264 + j*(84) -91 + j*(161) --64 + j*(-158) --34 + j*(-561) --90 + j*(-67) --67 + j*(-100) -117 + j*(-13) -16 + j*(-20) -144 + j*(128) -378 + j*(86) -96 + j*(-165) --218 + j*(-17) -78 + j*(281) -221 + j*(-293) -161 + j*(257) -170 + j*(98) --197 + j*(82) --374 + j*(211) -331 + j*(-194) -166 + j*(-191) -233 + j*(-141) -21 + j*(-85) --260 + j*(20) --378 + j*(212) -54 + j*(337) -217 + j*(342) -85 + j*(87) --145 + j*(105) -310 + j*(152) --69 + j*(137) -138 + j*(-73) --54 + j*(-25) --87 + j*(-16) -133 + j*(-134) -137 + j*(-126) -133 + j*(34) --137 + j*(7) -325 + j*(0) --141 + j*(185) -89 + j*(-3) --195 + j*(-91) -137 + j*(121) --211 + j*(-122) --57 + j*(88) --246 + j*(-217) -130 + j*(-260) --226 + j*(-54) --120 + j*(-135) -332 + j*(-94) --28 + j*(-57) -274 + j*(91) -49 + j*(-37) -173 + j*(119) -141 + j*(46) --79 + j*(-44) -95 + j*(-190) --48 + j*(-25) --94 + j*(-227) --261 + j*(-165) --60 + j*(87) --52 + j*(93) --146 + j*(-202) -24 + j*(-27) -110 + j*(-47) --88 + j*(-157) --37 + j*(305) --108 + j*(11) --304 + j*(-94) -0 + j*(86) -308 + j*(91) --243 + j*(121) -156 + j*(-95) -59 + j*(-81) --126 + j*(138) -177 + j*(32) --28 + j*(-145) -140 + j*(306) -44 + j*(-207) -4 + j*(-25) -69 + j*(91) --279 + j*(-240) --209 + j*(-70) --236 + j*(-49) --266 + j*(119) --29 + j*(40) -246 + j*(-281) --91 + j*(170) --66 + j*(-84) -257 + j*(-77) -169 + j*(205) --49 + j*(-64) -129 + j*(235) -153 + j*(-272) -25 + j*(167) -45 + j*(-199) -160 + j*(-20) --114 + j*(139) --255 + j*(-46) -276 + j*(-267) -145 + j*(72) -52 + j*(-160) --346 + j*(13) --107 + j*(203) --278 + j*(286) --279 + j*(300) --83 + j*(-110) -40 + j*(69) -77 + j*(-233) -177 + j*(55) -135 + j*(-241) -25 + j*(30) -100 + j*(81) -293 + j*(-232) --99 + j*(206) --428 + j*(232) -135 + j*(-12) -227 + j*(-14) -64 + j*(-328) -45 + j*(-37) --197 + j*(-253) -126 + j*(103) -113 + j*(4) --6 + j*(-86) -11 + j*(130) -45 + j*(-115) -3 + j*(141) --295 + j*(228) --132 + j*(-34) -328 + j*(7) --10 + j*(-414) -174 + j*(145) -108 + j*(-86) --244 + j*(10) --16 + j*(-123) --77 + j*(-84) -98 + j*(-405) -131 + j*(-130) --358 + j*(276) --59 + j*(-46) --523 + j*(75) --109 + j*(-81) --3 + j*(47) -197 + j*(207) -180 + j*(-38) -286 + j*(20) --299 + j*(-468) -107 + j*(-59) --273 + j*(-121) --14 + j*(-8) --58 + j*(-18) -123 + j*(266) -82 + j*(91) --117 + j*(70) -328 + j*(213) -165 + j*(-51) -234 + j*(-64) -192 + j*(-102) -25 + j*(81) --20 + j*(30) -54 + j*(-132) --57 + j*(91) -6 + j*(101) --6 + j*(66) -101 + j*(-100) -95 + j*(49) -160 + j*(272) -173 + j*(-262) -134 + j*(106) --59 + j*(9) -287 + j*(259) --105 + j*(-248) --156 + j*(-380) --287 + j*(141) --98 + j*(-66) -16 + j*(52) -63 + j*(103) -35 + j*(128) --104 + j*(-173) -86 + j*(226) -33 + j*(92) -149 + j*(49) -77 + j*(-76) --126 + j*(23) --417 + j*(13) --241 + j*(152) --30 + j*(-218) --176 + j*(-159) -93 + j*(105) -150 + j*(79) -163 + j*(66) -209 + j*(27) -21 + j*(-233) --144 + j*(16) -130 + j*(16) -322 + j*(192) --192 + j*(50) -230 + j*(-177) -98 + j*(-100) --127 + j*(-187) --153 + j*(33) -246 + j*(-37) -147 + j*(-141) --211 + j*(202) -265 + j*(177) -137 + j*(43) -538 + j*(218) --583 + j*(125) -52 + j*(42) -165 + j*(-288) --336 + j*(368) -175 + j*(-170) --441 + j*(240) -149 + j*(129) --235 + j*(148) --38 + j*(-30) --76 + j*(-467) -213 + j*(-158) -16 + j*(-30) --51 + j*(-43) --37 + j*(202) -16 + j*(-47) -199 + j*(-107) --161 + j*(105) --114 + j*(175) --57 + j*(-124) -13 + j*(-55) -148 + j*(-185) --76 + j*(-110) --127 + j*(95) -629 + j*(323) -75 + j*(-234) --103 + j*(-122) -88 + j*(-91) --88 + j*(-165) --19 + j*(47) --55 + j*(197) --31 + j*(-1) --206 + j*(52) --128 + j*(108) -218 + j*(58) --254 + j*(-185) --171 + j*(-105) -54 + j*(161) -31 + j*(41) --173 + j*(210) --4 + j*(45) --276 + j*(33) --270 + j*(92) -136 + j*(-105) -71 + j*(-156) -21 + j*(298) --134 + j*(284) -138 + j*(8) --62 + j*(483) --495 + j*(62) --231 + j*(-243) --231 + j*(139) -117 + j*(56) --121 + j*(-21) --205 + j*(-68) -46 + j*(-148) -272 + j*(-71) -22 + j*(-134) --88 + j*(170) -227 + j*(-7) -194 + j*(-216) --105 + j*(-83) -35 + j*(-38) --62 + j*(-11) --25 + j*(-57) --165 + j*(334) -59 + j*(-33) --66 + j*(54) -40 + j*(-2) --113 + j*(87) -61 + j*(-245) -47 + j*(-117) -71 + j*(-265) -177 + j*(298) -28 + j*(-226) -255 + j*(-117) -91 + j*(-88) --136 + j*(-4) -122 + j*(162) --66 + j*(156) --35 + j*(190) -112 + j*(233) -37 + j*(-218) --210 + j*(136) --117 + j*(199) --121 + j*(21) -21 + j*(42) --133 + j*(-1) -261 + j*(67) -274 + j*(-211) -117 + j*(109) --59 + j*(-67) --262 + j*(-350) -49 + j*(29) --164 + j*(-71) --7 + j*(148) --145 + j*(-25) -110 + j*(66) --63 + j*(-243) -45 + j*(371) -70 + j*(111) --69 + j*(-186) -170 + j*(-42) -7 + j*(18) --207 + j*(-57) -52 + j*(-413) -198 + j*(303) -42 + j*(-6) -162 + j*(131) --103 + j*(-41) --161 + j*(75) --18 + j*(137) -63 + j*(192) -317 + j*(201) --246 + j*(-300) -81 + j*(194) -410 + j*(-223) -168 + j*(109) --35 + j*(-319) --192 + j*(-197) --59 + j*(293) --138 + j*(-165) --124 + j*(-127) -161 + j*(-1) --225 + j*(252) -1 + j*(6) -66 + j*(-69) --95 + j*(33) -33 + j*(-151) --37 + j*(332) -38 + j*(-76) -113 + j*(-186) --132 + j*(-240) --67 + j*(125) --87 + j*(-121) --51 + j*(11) -436 + j*(-5) -5 + j*(4) -319 + j*(-137) -26 + j*(-105) --58 + j*(251) -49 + j*(-78) --159 + j*(-67) -82 + j*(177) --57 + j*(-229) -150 + j*(54) -39 + j*(-21) -23 + j*(-116) -83 + j*(154) --116 + j*(-146) -35 + j*(35) -129 + j*(66) --139 + j*(-21) --247 + j*(-43) -66 + j*(201) --48 + j*(-122) -115 + j*(-10) -59 + j*(-78) --135 + j*(325) -186 + j*(94) -321 + j*(64) --243 + j*(-163) --21 + j*(219) -92 + j*(18) --138 + j*(-308) -116 + j*(-98) --293 + j*(-9) --483 + j*(-84) --51 + j*(99) --34 + j*(-354) -44 + j*(124) --294 + j*(-137) --216 + j*(-135) -122 + j*(-151) --213 + j*(-472) --165 + j*(134) -184 + j*(-23) --178 + j*(-216) -71 + j*(-120) -35 + j*(107) --88 + j*(115) -394 + j*(-350) -261 + j*(-11) -18 + j*(69) -94 + j*(-419) -57 + j*(-196) --62 + j*(-337) --86 + j*(-111) --284 + j*(-116) --260 + j*(-87) --50 + j*(-44) -266 + j*(117) -37 + j*(-122) --249 + j*(80) -59 + j*(108) -151 + j*(-60) --13 + j*(60) -44 + j*(18) -233 + j*(108) -305 + j*(-136) --246 + j*(-6) --122 + j*(-25) --132 + j*(-170) --2 + j*(34) -93 + j*(-3) --87 + j*(93) -190 + j*(16) -192 + j*(314) -122 + j*(184) -185 + j*(272) --151 + j*(-226) -58 + j*(181) --39 + j*(-141) --36 + j*(-188) --96 + j*(158) --15 + j*(-67) --89 + j*(-180) -225 + j*(-103) -233 + j*(-173) -169 + j*(-23) --7 + j*(-106) -165 + j*(-170) --112 + j*(-73) --428 + j*(-307) --46 + j*(458) -235 + j*(-32) -255 + j*(268) -117 + j*(-291) -45 + j*(99) --194 + j*(-226) -103 + j*(-133) -107 + j*(-172) --18 + j*(-30) --3 + j*(-140) --146 + j*(-248) -127 + j*(12) --25 + j*(158) -199 + j*(170) -334 + j*(103) -38 + j*(218) --57 + j*(270) --229 + j*(6) --359 + j*(288) -100 + j*(107) -168 + j*(-62) -127 + j*(-205) --25 + j*(-194) -60 + j*(-344) --257 + j*(-204) -205 + j*(47) -63 + j*(6) -286 + j*(-307) -190 + j*(46) --404 + j*(24) -117 + j*(74) -17 + j*(-186) --358 + j*(70) --447 + j*(50) -317 + j*(-105) --300 + j*(-24) --170 + j*(-203) --18 + j*(-217) -401 + j*(59) --368 + j*(74) -227 + j*(-190) -150 + j*(6) -431 + j*(-158) -251 + j*(-187) --59 + j*(-158) --281 + j*(-172) --202 + j*(-277) -226 + j*(-39) --74 + j*(-202) -32 + j*(257) --249 + j*(-104) --342 + j*(18) --42 + j*(276) -20 + j*(-174) --58 + j*(55) -107 + j*(13) -62 + j*(110) --88 + j*(-8) --53 + j*(105) --98 + j*(-82) -40 + j*(-269) --168 + j*(146) --91 + j*(-114) --34 + j*(-367) --131 + j*(29) --137 + j*(58) --79 + j*(-44) --255 + j*(-166) --56 + j*(-137) --202 + j*(-279) -63 + j*(21) -383 + j*(-27) -19 + j*(252) -28 + j*(-19) --69 + j*(16) --136 + j*(275) -395 + j*(-137) -107 + j*(351) --59 + j*(279) --196 + j*(-284) -165 + j*(45) -68 + j*(-99) -404 + j*(303) --238 + j*(-18) -245 + j*(-265) -59 + j*(303) --35 + j*(-162) --453 + j*(-248) --334 + j*(163) --344 + j*(474) -6 + j*(-3) --201 + j*(269) -134 + j*(-625) -441 + j*(165) -89 + j*(-500) -170 + j*(475) -499 + j*(38) --637 + j*(-19) --191 + j*(444) --91 + j*(369) -129 + j*(270) -103 + j*(112) --11 + j*(255) -452 + j*(323) --325 + j*(-290) -485 + j*(-310) -238 + j*(-470) --148 + j*(-462) --323 + j*(-13) -175 + j*(-445) -381 + j*(-290) --479 + j*(-116) --348 + j*(245) -274 + j*(356) -54 + j*(233) -29 + j*(-153) -556 + j*(420) -88 + j*(27) --383 + j*(83) --45 + j*(606) -44 + j*(245) --272 + j*(-347) --452 + j*(-182) -35 + j*(165) -179 + j*(-366) --275 + j*(280) -294 + j*(-340) --371 + j*(200) --260 + j*(410) -210 + j*(-378) --54 + j*(371) -276 + j*(352) -524 + j*(361) -228 + j*(-63) --296 + j*(-247) -590 + j*(-115) --23 + j*(234) -71 + j*(255) --517 + j*(-235) -75 + j*(450) -89 + j*(-307) -180 + j*(313) -247 + j*(448) -197 + j*(98) -163 + j*(160) --272 + j*(182) -177 + j*(35) --397 + j*(201) --122 + j*(-438) --453 + j*(-634) --269 + j*(-228) --167 + j*(-662) -262 + j*(-260) -95 + j*(225) -477 + j*(356) --121 + j*(216) -77 + j*(161) --372 + j*(-286) --375 + j*(-124) --553 + j*(269) --320 + j*(-297) -158 + j*(-262) -456 + j*(-231) --440 + j*(-190) --234 + j*(182) -47 + j*(269) -122 + j*(54) --106 + j*(409) --245 + j*(228) --1 + j*(196) --120 + j*(-257) --173 + j*(80) --477 + j*(-206) -83 + j*(472) --611 + j*(176) -47 + j*(239) --474 + j*(89) -606 + j*(251) --338 + j*(451) -176 + j*(-199) --354 + j*(-397) --89 + j*(-178) -124 + j*(-152) -172 + j*(199) --367 + j*(-373) -461 + j*(-211) -341 + j*(63) -8 + j*(172) --398 + j*(109) -6 + j*(132) -422 + j*(139) --229 + j*(-193) --118 + j*(163) --74 + j*(105) --80 + j*(199) -622 + j*(-87) -206 + j*(-106) -62 + j*(117) --354 + j*(235) --129 + j*(-91) -413 + j*(430) --419 + j*(107) -236 + j*(187) --494 + j*(-507) --118 + j*(340) --25 + j*(335) -528 + j*(-308) --499 + j*(-47) --11 + j*(95) --275 + j*(259) --395 + j*(128) -35 + j*(264) --16 + j*(-187) -127 + j*(-355) -358 + j*(323) -517 + j*(13) --177 + j*(7) --335 + j*(-337) --570 + j*(210) -290 + j*(183) --529 + j*(-514) --87 + j*(272) --121 + j*(298) --682 + j*(-194) --99 + j*(228) --216 + j*(-336) -433 + j*(-46) --585 + j*(-307) --225 + j*(136) --92 + j*(-79) --38 + j*(413) --22 + j*(201) -272 + j*(311) -258 + j*(67) -19 + j*(-434) -417 + j*(343) --291 + j*(145) --197 + j*(173) -539 + j*(430) --530 + j*(-280) --69 + j*(276) --442 + j*(71) --363 + j*(-136) --390 + j*(245) --186 + j*(326) -426 + j*(217) -83 + j*(467) --613 + j*(281) -146 + j*(-255) -37 + j*(-203) --504 + j*(49) --48 + j*(-541) -165 + j*(33) --302 + j*(296) --528 + j*(73) --281 + j*(-112) -455 + j*(547) -245 + j*(-219) --552 + j*(-479) --163 + j*(-419) -235 + j*(424) --527 + j*(240) -25 + j*(-750) --203 + j*(-203) --205 + j*(-281) --88 + j*(88) -353 + j*(597) -362 + j*(287) --308 + j*(175) -569 + j*(180) -421 + j*(-441) --382 + j*(76) --40 + j*(180) --81 + j*(235) --308 + j*(169) -364 + j*(-674) --218 + j*(49) -437 + j*(369) -251 + j*(-216) -395 + j*(-381) --255 + j*(113) --411 + j*(300) --109 + j*(83) --132 + j*(512) -194 + j*(336) --83 + j*(283) -340 + j*(-88) -47 + j*(156) --71 + j*(293) -467 + j*(389) -269 + j*(-11) --188 + j*(-217) --266 + j*(220) --368 + j*(402) --394 + j*(153) --148 + j*(-221) -132 + j*(-19) -284 + j*(-238) --255 + j*(-104) --399 + j*(-474) --693 + j*(211) --318 + j*(97) --568 + j*(-313) -206 + j*(10) -339 + j*(-526) --535 + j*(-288) --4 + j*(-254) -537 + j*(140) --313 + j*(377) -59 + j*(164) -257 + j*(258) -387 + j*(-396) -252 + j*(650) -144 + j*(-562) --56 + j*(-597) --163 + j*(377) --89 + j*(488) --245 + j*(-170) --94 + j*(-573) --248 + j*(374) -327 + j*(-499) --438 + j*(89) -228 + j*(-331) -40 + j*(-243) -205 + j*(320) --280 + j*(-1) -380 + j*(-342) --539 + j*(176) -37 + j*(-398) --567 + j*(474) --322 + j*(319) -118 + j*(222) --317 + j*(-47) -304 + j*(-267) -355 + j*(-300) -146 + j*(256) --330 + j*(-215) -23 + j*(435) -354 + j*(83) -231 + j*(90) -152 + j*(-227) --246 + j*(262) --451 + j*(341) --208 + j*(-239) -256 + j*(-187) --474 + j*(-392) -293 + j*(-143) -397 + j*(273) -349 + j*(150) -211 + j*(62) --249 + j*(-354) -76 + j*(213) --129 + j*(-209) --555 + j*(-134) -264 + j*(-363) -457 + j*(-358) --165 + j*(-33) -149 + j*(-256) -190 + j*(136) -182 + j*(190) -371 + j*(287) -252 + j*(56) -395 + j*(391) -308 + j*(-521) -45 + j*(-256) --9 + j*(-543) -323 + j*(407) -486 + j*(-177) --363 + j*(29) -206 + j*(-639) --333 + j*(-112) -71 + j*(-152) -21 + j*(-375) -154 + j*(39) --103 + j*(-450) --281 + j*(-57) --215 + j*(428) --332 + j*(-16) -349 + j*(-7) --145 + j*(-528) -226 + j*(295) -472 + j*(-151) -56 + j*(241) -144 + j*(75) --641 + j*(-214) -316 + j*(303) --523 + j*(-491) -504 + j*(373) -170 + j*(419) --469 + j*(-817) -76 + j*(163) -204 + j*(-40) --467 + j*(-346) --181 + j*(93) --25 + j*(-513) -204 + j*(446) -525 + j*(229) --499 + j*(383) --91 + j*(288) -33 + j*(-115) -8 + j*(-433) --238 + j*(-446) -156 + j*(496) -207 + j*(17) --271 + j*(-318) -287 + j*(-330) --212 + j*(-262) --62 + j*(-20) -617 + j*(157) --40 + j*(-72) --256 + j*(-126) -313 + j*(-422) --209 + j*(23) -433 + j*(-441) -175 + j*(-378) --223 + j*(16) --1 + j*(-623) -441 + j*(-211) --243 + j*(-511) --370 + j*(-292) --114 + j*(-321) --347 + j*(-197) --501 + j*(-327) -57 + j*(-296) --231 + j*(241) -148 + j*(68) --516 + j*(391) -250 + j*(-153) --300 + j*(-183) --9 + j*(-402) -332 + j*(197) -209 + j*(280) -115 + j*(-447) --167 + j*(66) -455 + j*(105) -307 + j*(98) -409 + j*(-368) -37 + j*(-124) -137 + j*(238) --402 + j*(-307) --319 + j*(-198) -37 + j*(-339) -223 + j*(199) --354 + j*(-160) --3 + j*(401) --11 + j*(30) -377 + j*(-197) --639 + j*(-83) --15 + j*(296) -79 + j*(-421) --197 + j*(-234) --47 + j*(-387) -629 + j*(30) -293 + j*(170) -595 + j*(486) --391 + j*(256) --44 + j*(25) --497 + j*(364) --74 + j*(198) -127 + j*(322) --373 + j*(161) --200 + j*(67) -503 + j*(301) -319 + j*(209) -276 + j*(-260) --539 + j*(-240) --53 + j*(356) -340 + j*(-97) -28 + j*(321) -45 + j*(-135) -1 + j*(-404) -319 + j*(-499) -457 + j*(-78) -178 + j*(-281) --399 + j*(-112) -124 + j*(-13) --195 + j*(-286) -132 + j*(354) -677 + j*(-21) --69 + j*(-286) -571 + j*(197) -141 + j*(17) -126 + j*(282) -176 + j*(611) -419 + j*(-260) -202 + j*(-305) -196 + j*(-390) --696 + j*(547) -226 + j*(-73) -187 + j*(537) --245 + j*(276) --508 + j*(139) -364 + j*(235) -438 + j*(-310) -284 + j*(-198) --246 + j*(616) -346 + j*(-528) -190 + j*(365) -279 + j*(310) --286 + j*(287) --128 + j*(-385) --150 + j*(461) -305 + j*(81) --167 + j*(305) -177 + j*(310) --1 + j*(-93) --322 + j*(450) --278 + j*(-342) -549 + j*(328) --168 + j*(540) -351 + j*(-178) -217 + j*(314) --275 + j*(300) -163 + j*(-137) --153 + j*(-810) --314 + j*(457) -279 + j*(-263) -157 + j*(-163) -622 + j*(-212) -70 + j*(-303) -275 + j*(-532) -321 + j*(409) -134 + j*(293) --91 + j*(-387) -272 + j*(127) --312 + j*(-547) --226 + j*(-198) --518 + j*(583) -117 + j*(218) -658 + j*(19) -317 + j*(691) --420 + j*(193) -62 + j*(-383) --79 + j*(-174) -74 + j*(348) -354 + j*(-148) --478 + j*(-88) -393 + j*(-581) -282 + j*(16) -214 + j*(416) --163 + j*(-387) -226 + j*(-209) -44 + j*(-400) -345 + j*(-215) --203 + j*(-110) -269 + j*(301) --269 + j*(75) -199 + j*(471) --320 + j*(1) --648 + j*(-421) -245 + j*(-436) --57 + j*(183) --571 + j*(21) --403 + j*(158) -427 + j*(218) --327 + j*(-246) -529 + j*(459) -150 + j*(127) --418 + j*(-54) -412 + j*(369) -116 + j*(-91) -395 + j*(296) -301 + j*(276) -566 + j*(285) -15 + j*(-486) -267 + j*(511) --98 + j*(-312) --190 + j*(-24) --30 + j*(-380) --484 + j*(-349) --109 + j*(85) --43 + j*(-262) -320 + j*(355) --552 + j*(-317) --95 + j*(250) -358 + j*(277) --62 + j*(-587) -128 + j*(-55) --302 + j*(127) --338 + j*(-502) --90 + j*(-230) --271 + j*(-47) -638 + j*(-255) -330 + j*(-83) --233 + j*(421) --182 + j*(-139) --32 + j*(405) -296 + j*(157) -28 + j*(216) -129 + j*(1) --267 + j*(-117) --310 + j*(-152) --390 + j*(-285) -389 + j*(371) -199 + j*(165) -120 + j*(45) -530 + j*(354) --42 + j*(-301) -368 + j*(-213) --28 + j*(-317) --89 + j*(-516) --32 + j*(213) -218 + j*(105) --168 + j*(293) --261 + j*(225) -158 + j*(221) --180 + j*(-234) -236 + j*(383) --63 + j*(-86) -319 + j*(-243) -265 + j*(60) --63 + j*(149) -191 + j*(-45) --172 + j*(202) --212 + j*(616) --405 + j*(387) --325 + j*(19) --18 + j*(149) --594 + j*(-148) --387 + j*(460) --368 + j*(469) -407 + j*(310) --475 + j*(6) --474 + j*(30) --553 + j*(331) --99 + j*(-116) -265 + j*(-308) -188 + j*(-201) -64 + j*(-253) --30 + j*(-274) --364 + j*(322) -309 + j*(-317) --293 + j*(223) -197 + j*(-407) -433 + j*(-237) --73 + j*(37) -392 + j*(373) --235 + j*(-14) -425 + j*(-168) --192 + j*(49) -15 + j*(-447) -61 + j*(202) -374 + j*(-368) -393 + j*(-243) -383 + j*(-417) -214 + j*(-48) --228 + j*(148) --298 + j*(-249) -55 + j*(-243) -269 + j*(-70) -230 + j*(85) -402 + j*(-211) --491 + j*(-202) --465 + j*(-66) -556 + j*(352) -105 + j*(473) -358 + j*(-113) --377 + j*(244) --344 + j*(-247) --160 + j*(233) -437 + j*(-361) -288 + j*(184) -94 + j*(-404) --11 + j*(205) --216 + j*(-250) --11 + j*(-221) --1 + j*(-287) -269 + j*(-443) -244 + j*(-533) --298 + j*(-8) --180 + j*(109) -248 + j*(479) -213 + j*(124) -358 + j*(541) --181 + j*(-170) --250 + j*(187) -117 + j*(-116) --319 + j*(226) -206 + j*(124) --320 + j*(-134) -241 + j*(518) --218 + j*(6) --407 + j*(-465) -93 + j*(479) --550 + j*(275) -112 + j*(623) --153 + j*(102) --38 + j*(-216) -125 + j*(-53) -243 + j*(-223) --298 + j*(-80) -358 + j*(153) --172 + j*(99) --166 + j*(-334) --24 + j*(136) --269 + j*(83) --16 + j*(141) --81 + j*(-37) -288 + j*(-160) -76 + j*(-252) -15 + j*(-38) -52 + j*(-147) --139 + j*(-18) --134 + j*(163) --214 + j*(-61) --187 + j*(259) -317 + j*(-68) --102 + j*(-43) --310 + j*(-237) -28 + j*(-4) --106 + j*(21) -106 + j*(-231) --339 + j*(50) -30 + j*(-218) --42 + j*(-162) --235 + j*(-288) --110 + j*(-78) -95 + j*(413) --305 + j*(67) -238 + j*(279) -124 + j*(196) --105 + j*(-66) --495 + j*(-67) -190 + j*(62) --241 + j*(-206) -99 + j*(3) --175 + j*(-147) -78 + j*(-20) --103 + j*(-211) --167 + j*(-285) -54 + j*(-207) -88 + j*(11) -21 + j*(35) --62 + j*(13) -317 + j*(199) -113 + j*(122) --373 + j*(252) -94 + j*(-60) -35 + j*(117) --180 + j*(194) --21 + j*(81) -21 + j*(87) --96 + j*(-382) --185 + j*(100) --463 + j*(392) --78 + j*(-193) -312 + j*(-53) --126 + j*(-49) -217 + j*(52) --62 + j*(187) --66 + j*(76) --37 + j*(-108) -82 + j*(-197) -37 + j*(-62) -45 + j*(-120) -83 + j*(-103) --91 + j*(165) --77 + j*(90) --224 + j*(160) --145 + j*(67) -230 + j*(-203) -143 + j*(54) -223 + j*(163) -42 + j*(-2) -39 + j*(-60) -2 + j*(235) -216 + j*(274) -34 + j*(-177) -138 + j*(-175) --220 + j*(-211) --15 + j*(36) --23 + j*(300) -91 + j*(282) --3 + j*(166) --193 + j*(-123) --103 + j*(27) --5 + j*(28) --121 + j*(60) -243 + j*(-2) -145 + j*(-293) --127 + j*(415) --83 + j*(267) --95 + j*(47) -35 + j*(96) --53 + j*(-190) -18 + j*(-146) --76 + j*(165) -131 + j*(-103) -5 + j*(-44) -57 + j*(-155) --339 + j*(-77) -8 + j*(-175) -157 + j*(16) -119 + j*(149) --276 + j*(-163) -23 + j*(107) -69 + j*(-146) -135 + j*(-267) -94 + j*(103) -27 + j*(57) -29 + j*(164) -24 + j*(-66) --98 + j*(-193) --9 + j*(51) --144 + j*(-103) -346 + j*(59) -377 + j*(262) -82 + j*(-277) -60 + j*(143) -88 + j*(107) -192 + j*(-120) --146 + j*(-35) --455 + j*(107) -91 + j*(236) -181 + j*(45) -90 + j*(64) --56 + j*(-392) --73 + j*(-43) -99 + j*(9) --270 + j*(-105) --62 + j*(-435) --349 + j*(-218) --298 + j*(-86) --137 + j*(-90) -76 + j*(28) -235 + j*(-12) --63 + j*(-119) --180 + j*(71) --165 + j*(218) --96 + j*(-2) -1 + j*(-390) --1 + j*(5) -59 + j*(-162) -33 + j*(171) -9 + j*(-5) -387 + j*(-101) --89 + j*(94) --168 + j*(-165) --230 + j*(-2) -446 + j*(198) -209 + j*(161) -172 + j*(153) -34 + j*(153) -80 + j*(3) --238 + j*(245) --28 + j*(-286) -261 + j*(202) --277 + j*(139) -76 + j*(148) -321 + j*(-148) -5 + j*(-124) -175 + j*(286) --22 + j*(95) -14 + j*(-212) --30 + j*(-224) --52 + j*(-112) -240 + j*(-124) --21 + j*(292) --39 + j*(-235) -81 + j*(262) -3 + j*(-186) -74 + j*(-12) -178 + j*(84) -86 + j*(-62) -238 + j*(-4) -4 + j*(13) -265 + j*(-82) -37 + j*(218) --187 + j*(71) --288 + j*(330) --112 + j*(340) -71 + j*(-57) --62 + j*(81) -18 + j*(96) --84 + j*(132) -10 + j*(162) -97 + j*(4) -50 + j*(308) --25 + j*(442) --136 + j*(187) --161 + j*(109) --50 + j*(54) -210 + j*(-192) -59 + j*(174) --51 + j*(-252) -139 + j*(-155) -280 + j*(156) -32 + j*(-54) -211 + j*(24) --198 + j*(-298) -165 + j*(206) -122 + j*(-144) -30 + j*(119) --21 + j*(281) -74 + j*(-119) --54 + j*(-23) --25 + j*(332) -78 + j*(-199) --125 + j*(-74) -232 + j*(11) --199 + j*(154) -311 + j*(31) -76 + j*(307) -39 + j*(-23) --165 + j*(397) -310 + j*(42) -255 + j*(-36) -276 + j*(-68) --192 + j*(20) --98 + j*(166) -3 + j*(-489) -41 + j*(177) --72 + j*(305) --52 + j*(-67) -66 + j*(-297) -20 + j*(-185) --270 + j*(-66) -15 + j*(-18) --71 + j*(-7) -40 + j*(-203) -199 + j*(-431) -316 + j*(-88) -46 + j*(90) --196 + j*(38) -91 + j*(-21) --1 + j*(169) -96 + j*(36) --76 + j*(-205) -289 + j*(76) --132 + j*(-141) --145 + j*(-97) --1 + j*(171) --51 + j*(182) -19 + j*(-129) -40 + j*(50) --175 + j*(-300) -21 + j*(74) -51 + j*(142) --128 + j*(-64) --43 + j*(-92) -247 + j*(109) --53 + j*(-28) --20 + j*(-168) -47 + j*(331) -8 + j*(-158) --7 + j*(-202) --51 + j*(-9) -49 + j*(66) -26 + j*(67) --157 + j*(-441) -82 + j*(-47) --124 + j*(165) --134 + j*(201) --74 + j*(184) -201 + j*(-29) -85 + j*(-272) -68 + j*(-132) -138 + j*(-243) --44 + j*(170) --154 + j*(-1) --93 + j*(79) -132 + j*(-134) --168 + j*(132) -147 + j*(144) --113 + j*(-10) -88 + j*(124) --267 + j*(25) -63 + j*(-53) -156 + j*(-330) -75 + j*(167) -238 + j*(0) -189 + j*(29) --175 + j*(-159) -110 + j*(-90) --68 + j*(-70) -36 + j*(-15) -6 + j*(-356) -138 + j*(315) -17 + j*(-114) --239 + j*(129) -279 + j*(21) --151 + j*(-25) -103 + j*(-17) -213 + j*(8) --81 + j*(148) --171 + j*(24) --63 + j*(6) -178 + j*(-13) -115 + j*(115) -187 + j*(148) --191 + j*(-442) --9 + j*(218) --60 + j*(101) --64 + j*(191) --21 + j*(-170) -78 + j*(110) --395 + j*(216) -122 + j*(186) --81 + j*(2) --324 + j*(237) -26 + j*(-274) -60 + j*(-154) --54 + j*(-83) -9 + j*(240) --117 + j*(63) --10 + j*(3) -109 + j*(124) -55 + j*(-28) -51 + j*(-1) -293 + j*(-194) --88 + j*(-208) --58 + j*(-27) -48 + j*(117) --287 + j*(97) --105 + j*(-250) --2 + j*(-269) --204 + j*(-248) --189 + j*(-123) --134 + j*(206) --114 + j*(-123) --180 + j*(-58) --320 + j*(-144) --265 + j*(-50) -243 + j*(-311) -48 + j*(25) --69 + j*(-78) --98 + j*(25) --3 + j*(-18) -63 + j*(-254) --182 + j*(-132) -122 + j*(-55) --43 + j*(161) --257 + j*(219) -1 + j*(-32) -417 + j*(64) --131 + j*(199) --215 + j*(-242) -308 + j*(153) -157 + j*(-10) --199 + j*(164) --77 + j*(-54) --68 + j*(76) --22 + j*(-71) -101 + j*(95) --223 + j*(-192) --94 + j*(113) --256 + j*(-165) -420 + j*(131) -62 + j*(0) --168 + j*(95) --69 + j*(-202) -137 + j*(1) -226 + j*(439) -153 + j*(-33) --76 + j*(81) --264 + j*(30) -400 + j*(62) -175 + j*(-37) -343 + j*(-157) --302 + j*(59) -246 + j*(114) -148 + j*(-61) -112 + j*(74) --134 + j*(-46) --243 + j*(41) -255 + j*(-355) --85 + j*(-38) --110 + j*(183) -132 + j*(95) --566 + j*(169) -313 + j*(162) --31 + j*(-28) --245 + j*(442) --64 + j*(-252) -334 + j*(-138) -105 + j*(-85) --135 + j*(16) -123 + j*(-224) -62 + j*(-48) --78 + j*(-16) --272 + j*(74) -66 + j*(222) -49 + j*(269) --255 + j*(-76) --192 + j*(-3) -11 + j*(-50) -168 + j*(293) -76 + j*(110) --43 + j*(99) -187 + j*(61) --340 + j*(-91) --110 + j*(-132) --156 + j*(-99) -149 + j*(103) -203 + j*(-56) -37 + j*(261) --232 + j*(78) -44 + j*(13) -139 + j*(-14) --58 + j*(-137) --52 + j*(-281) --231 + j*(35) -211 + j*(-35) -42 + j*(65) --177 + j*(223) -127 + j*(61) -148 + j*(-34) -101 + j*(224) --8 + j*(91) --49 + j*(157) --174 + j*(-173) --47 + j*(-56) --55 + j*(115) --108 + j*(-19) --147 + j*(-96) --132 + j*(-86) --23 + j*(23) -183 + j*(-191) -265 + j*(107) --83 + j*(306) -50 + j*(239) -137 + j*(-273) -330 + j*(52) --153 + j*(45) --191 + j*(306) -171 + j*(-64) --16 + j*(78) --298 + j*(-16) -94 + j*(410) --125 + j*(65) --154 + j*(112) -81 + j*(69) --151 + j*(-175) -294 + j*(-264) --119 + j*(286) --35 + j*(-293) -49 + j*(221) --77 + j*(-30) --170 + j*(407) --198 + j*(14) --5 + j*(6) -315 + j*(-35) -41 + j*(282) -241 + j*(25) -148 + j*(168) -34 + j*(196) --248 + j*(161) -129 + j*(-66) -296 + j*(-42) --45 + j*(119) --87 + j*(141) -86 + j*(90) -66 + j*(-45) --13 + j*(-129) -273 + j*(-148) --6 + j*(-82) -227 + j*(-168) -32 + j*(-130) -59 + j*(-64) -11 + j*(99) --91 + j*(-40) -208 + j*(-91) -218 + j*(69) -48 + j*(-325) -6 + j*(47) -6 + j*(-215) --250 + j*(-271) --98 + j*(36) --180 + j*(-23) --371 + j*(-30) --242 + j*(-11) -191 + j*(6) -70 + j*(-28) --90 + j*(171) -208 + j*(-58) -3 + j*(101) -122 + j*(-214) -13 + j*(99) --80 + j*(217) --315 + j*(182) -124 + j*(-228) -192 + j*(177) -330 + j*(61) --270 + j*(-122) --5 + j*(-162) -182 + j*(31) --197 + j*(-168) -11 + j*(123) -86 + j*(277) --37 + j*(-84) -164 + j*(-81) -148 + j*(24) -355 + j*(-25) -149 + j*(54) --36 + j*(158) -189 + j*(-11) -127 + j*(141) -76 + j*(130) --32 + j*(33) --189 + j*(-19) --35 + j*(-350) --133 + j*(252) --139 + j*(-38) -71 + j*(-33) --42 + j*(-138) --252 + j*(121) -283 + j*(140) --50 + j*(135) --124 + j*(-32) -124 + j*(289) --84 + j*(153) -197 + j*(134) --80 + j*(434) --41 + j*(71) -159 + j*(-46) -30 + j*(321) -165 + j*(-438) --47 + j*(98) -180 + j*(125) --144 + j*(-28) -292 + j*(-85) --129 + j*(168) --117 + j*(54) -100 + j*(-224) -25 + j*(-146) -397 + j*(-4) -81 + j*(37) --47 + j*(8) -20 + j*(-333) -110 + j*(-108) --198 + j*(236) --209 + j*(-77) -35 + j*(-111) --82 + j*(78) --46 + j*(-170) -150 + j*(153) -210 + j*(37) --378 + j*(-346) -122 + j*(105) --48 + j*(128) -4 + j*(250) --42 + j*(233) --59 + j*(46) -132 + j*(-116) --69 + j*(51) --296 + j*(228) --81 + j*(40) -121 + j*(-190) -111 + j*(60) --33 + j*(-152) --71 + j*(145) --310 + j*(-11) --144 + j*(-107) -91 + j*(134) --54 + j*(134) -15 + j*(154) -110 + j*(191) --214 + j*(-2) -504 + j*(-209) --42 + j*(-76) -284 + j*(75) --138 + j*(-303) --53 + j*(110) -120 + j*(74) -240 + j*(131) -272 + j*(-115) -3 + j*(69) --32 + j*(18) -259 + j*(-187) -127 + j*(179) --197 + j*(187) -337 + j*(-229) --2 + j*(-35) -188 + j*(25) --348 + j*(177) -138 + j*(-299) --150 + j*(169) -140 + j*(231) --232 + j*(92) --8 + j*(131) --88 + j*(144) -54 + j*(-169) --54 + j*(95) -46 + j*(-153) -74 + j*(112) --187 + j*(-75) --163 + j*(-105) --109 + j*(95) --149 + j*(-81) --320 + j*(128) -245 + j*(117) --284 + j*(93) --26 + j*(-222) --240 + j*(144) -30 + j*(-30) --11 + j*(327) -148 + j*(68) -149 + j*(37) --110 + j*(-209) -348 + j*(7) --69 + j*(-78) -207 + j*(13) --160 + j*(-16) --59 + j*(-75) -70 + j*(7) -203 + j*(220) -301 + j*(210) --206 + j*(-198) -24 + j*(115) --163 + j*(-298) -115 + j*(104) -222 + j*(290) --147 + j*(-90) --254 + j*(-416) -123 + j*(-111) -11 + j*(-310) --179 + j*(-358) -334 + j*(-325) --4 + j*(-132) -35 + j*(134) -5 + j*(-226) -243 + j*(-151) -28 + j*(15) --40 + j*(62) -37 + j*(179) -308 + j*(-266) --185 + j*(-283) -116 + j*(107) -374 + j*(-155) -270 + j*(137) --241 + j*(292) -170 + j*(-226) -55 + j*(-2) -40 + j*(-28) --175 + j*(8) --221 + j*(-73) --51 + j*(-106) --148 + j*(-103) -109 + j*(143) -6 + j*(203) -149 + j*(239) --368 + j*(-54) -95 + j*(249) -210 + j*(64) -13 + j*(-30) -302 + j*(80) -409 + j*(-78) -76 + j*(-308) --71 + j*(-169) --23 + j*(-222) -33 + j*(80) --338 + j*(-320) -45 + j*(-105) --66 + j*(-274) -70 + j*(-21) -48 + j*(27) -189 + j*(257) --64 + j*(7) --117 + j*(-42) --28 + j*(-128) --148 + j*(-406) --174 + j*(-208) -198 + j*(-69) -147 + j*(-133) -257 + j*(-138) --231 + j*(17) -127 + j*(-88) -88 + j*(42) --126 + j*(36) --63 + j*(-175) -123 + j*(-173) --252 + j*(-136) --198 + j*(122) --290 + j*(237) -22 + j*(-23) -171 + j*(89) -239 + j*(-141) -11 + j*(-109) -301 + j*(-88) --216 + j*(1) -14 + j*(-177) -47 + j*(6) --161 + j*(20) --186 + j*(-78) -173 + j*(-47) --289 + j*(-68) --81 + j*(83) --77 + j*(164) -220 + j*(-20) --106 + j*(177) --292 + j*(-216) -74 + j*(-34) -245 + j*(1) -4 + j*(383) --30 + j*(-119) -221 + j*(180) -139 + j*(-260) --160 + j*(95) -58 + j*(361) --223 + j*(57) --59 + j*(-59) --82 + j*(-51) -105 + j*(35) -59 + j*(146) --158 + j*(-41) --64 + j*(197) --202 + j*(-83) -191 + j*(-335) -129 + j*(-421) --30 + j*(-118) -69 + j*(129) --116 + j*(-67) --366 + j*(-18) -279 + j*(235) --279 + j*(1) -45 + j*(-96) --13 + j*(-238) -382 + j*(-21) -207 + j*(351) -192 + j*(-107) --103 + j*(-137) --90 + j*(110) --262 + j*(-211) --127 + j*(162) -109 + j*(40) --238 + j*(127) -81 + j*(5) --30 + j*(109) -118 + j*(71) --12 + j*(26) -40 + j*(-161) -23 + j*(124) --23 + j*(25) --374 + j*(-62) -154 + j*(448) --66 + j*(-63) -152 + j*(-354) -409 + j*(-129) --469 + j*(96) --4 + j*(-141) --13 + j*(142) -276 + j*(12) --135 + j*(-289) --50 + j*(181) --205 + j*(-146) -196 + j*(255) --200 + j*(23) -279 + j*(52) --76 + j*(196) -40 + j*(98) --62 + j*(211) -74 + j*(73) --161 + j*(-179) --134 + j*(-2) --18 + j*(-132) -444 + j*(21) --194 + j*(69) --92 + j*(25) --119 + j*(-431) -121 + j*(136) --100 + j*(63) -14 + j*(-67) -66 + j*(234) --35 + j*(288) -356 + j*(-111) --74 + j*(-60) -215 + j*(206) --46 + j*(8) --4 + j*(-153) --135 + j*(-165) -274 + j*(-99) --218 + j*(-60) --7 + j*(145) --282 + j*(-132) --21 + j*(-270) -35 + j*(-186) -59 + j*(161) --148 + j*(-212) --452 + j*(-222) -203 + j*(-168) -16 + j*(142) -177 + j*(448) -56 + j*(-74) --37 + j*(119) --47 + j*(48) -192 + j*(30) --243 + j*(67) --199 + j*(78) -197 + j*(103) -164 + j*(-210) --33 + j*(185) --55 + j*(35) --388 + j*(21) --49 + j*(-101) --27 + j*(-276) --197 + j*(-151) --236 + j*(-178) --32 + j*(-162) --78 + j*(257) --75 + j*(85) -157 + j*(-10) --147 + j*(-3) -21 + j*(-8) -120 + j*(120) -132 + j*(98) --140 + j*(-98) -194 + j*(-322) -113 + j*(-51) -177 + j*(-63) -41 + j*(204) -146 + j*(45) --145 + j*(62) -17 + j*(74) -257 + j*(-247) --16 + j*(-193) --33 + j*(-364) --297 + j*(100) -18 + j*(-268) --79 + j*(-70) -49 + j*(17) --61 + j*(-52) -296 + j*(-32) -37 + j*(168) --117 + j*(-164) --74 + j*(-211) --87 + j*(66) --165 + j*(-38) -18 + j*(136) -14 + j*(74) -187 + j*(172) -99 + j*(22) -95 + j*(-151) -88 + j*(-236) --201 + j*(92) -91 + j*(214) -280 + j*(200) -254 + j*(-28) -82 + j*(199) --333 + j*(294) --64 + j*(-255) -228 + j*(375) --1 + j*(94) -211 + j*(-207) -299 + j*(-447) --104 + j*(-17) --30 + j*(-28) --164 + j*(-211) --87 + j*(-76) --124 + j*(264) -176 + j*(-222) -221 + j*(-322) -158 + j*(148) --307 + j*(-128) -86 + j*(9) --10 + j*(-23) -131 + j*(25) --108 + j*(186) --144 + j*(132) -67 + j*(121) -11 + j*(-222) -1 + j*(93) -182 + j*(93) --114 + j*(200) -87 + j*(163) -88 + j*(86) --73 + j*(-90) -123 + j*(-30) --16 + j*(-27) -214 + j*(-188) --36 + j*(25) --286 + j*(310) --202 + j*(-54) --223 + j*(238) --161 + j*(54) --62 + j*(170) --214 + j*(-35) -110 + j*(264) -262 + j*(265) -100 + j*(37) --488 + j*(305) --148 + j*(254) --253 + j*(123) -146 + j*(182) --332 + j*(-199) -55 + j*(-65) -204 + j*(83) --1 + j*(-51) -32 + j*(-314) -43 + j*(23) -68 + j*(-412) -78 + j*(-180) --197 + j*(146) --76 + j*(-66) -136 + j*(-226) -40 + j*(241) -27 + j*(-177) --144 + j*(66) -112 + j*(-258) -163 + j*(-74) --1 + j*(-81) -52 + j*(469) -3 + j*(-276) -148 + j*(107) --93 + j*(-173) -64 + j*(37) --231 + j*(124) -61 + j*(-131) --88 + j*(114) -107 + j*(-32) --170 + j*(240) -226 + j*(-173) -58 + j*(-247) -22 + j*(47) -168 + j*(181) -16 + j*(158) --120 + j*(-66) --81 + j*(296) --209 + j*(-192) --75 + j*(-115) -95 + j*(86) -32 + j*(125) -57 + j*(64) -6 + j*(-11) --367 + j*(-47) -180 + j*(-28) --443 + j*(-35) --174 + j*(67) --83 + j*(-21) -64 + j*(-84) -206 + j*(-67) -25 + j*(-205) --205 + j*(139) -16 + j*(-135) --233 + j*(-43) -158 + j*(-4) --18 + j*(-106) --87 + j*(129) --112 + j*(-28) -159 + j*(144) -98 + j*(-110) --11 + j*(28) --41 + j*(192) -21 + j*(-199) --26 + j*(233) -6 + j*(-337) -412 + j*(7) --136 + j*(-25) -83 + j*(103) --45 + j*(62) -79 + j*(20) -86 + j*(20) -142 + j*(284) --45 + j*(-91) -100 + j*(67) --142 + j*(100) --223 + j*(248) --3 + j*(120) -311 + j*(-245) -62 + j*(-47) -91 + j*(-78) --141 + j*(-132) -4 + j*(-133) -81 + j*(-179) --13 + j*(166) -20 + j*(180) -182 + j*(-139) -230 + j*(83) -387 + j*(67) --6 + j*(-113) -63 + j*(161) --198 + j*(104) --36 + j*(-129) --30 + j*(-63) -112 + j*(-41) -127 + j*(189) -156 + j*(62) --110 + j*(-12) -52 + j*(-182) --110 + j*(-298) --151 + j*(180) -234 + j*(-178) -14 + j*(69) -75 + j*(-57) -236 + j*(-168) --54 + j*(-212) --194 + j*(15) -80 + j*(347) -190 + j*(412) -11 + j*(-153) -59 + j*(28) --182 + j*(-11) -54 + j*(145) -69 + j*(78) -166 + j*(-189) -204 + j*(-157) -83 + j*(-216) -87 + j*(-35) --200 + j*(-156) -455 + j*(141) -7 + j*(-114) -91 + j*(305) --95 + j*(62) --254 + j*(-61) --80 + j*(117) --30 + j*(-195) --146 + j*(105) -21 + j*(-25) -305 + j*(23) --81 + j*(-15) -192 + j*(395) -141 + j*(303) --52 + j*(-129) -54 + j*(-149) -63 + j*(64) -98 + j*(-260) -132 + j*(19) --59 + j*(-57) -116 + j*(170) -251 + j*(-284) -42 + j*(208) -51 + j*(-195) --98 + j*(-44) --57 + j*(55) -106 + j*(-38) --243 + j*(16) -153 + j*(-65) -7 + j*(-110) -88 + j*(-73) --279 + j*(77) --173 + j*(40) --112 + j*(0) --154 + j*(-228) -2 + j*(-147) --166 + j*(126) -119 + j*(148) --215 + j*(114) --155 + j*(23) --41 + j*(-34) -40 + j*(-300) --328 + j*(202) --206 + j*(-212) -59 + j*(-325) -25 + j*(-100) --208 + j*(-235) --233 + j*(167) --243 + j*(20) --203 + j*(0) --168 + j*(-173) --310 + j*(-146) --148 + j*(398) --72 + j*(-93) -62 + j*(-152) -28 + j*(128) --217 + j*(-27) --222 + j*(-188) -168 + j*(16) --100 + j*(140) -99 + j*(8) -76 + j*(-57) -139 + j*(-150) --192 + j*(-49) --18 + j*(-206) --16 + j*(-327) -78 + j*(35) -11 + j*(42) --107 + j*(-82) --274 + j*(235) -81 + j*(-11) -281 + j*(-61) --148 + j*(78) --279 + j*(-51) --252 + j*(186) -31 + j*(-99) -292 + j*(-155) --188 + j*(192) -258 + j*(-96) -21 + j*(-92) --28 + j*(165) -146 + j*(59) -0 + j*(-21) -30 + j*(-192) -82 + j*(14) --294 + j*(-13) --150 + j*(137) --71 + j*(68) --233 + j*(45) -12 + j*(-62) --177 + j*(44) --175 + j*(337) --41 + j*(1) -363 + j*(-244) -231 + j*(181) -191 + j*(-130) -287 + j*(115) --69 + j*(221) --236 + j*(-50) --393 + j*(-47) -71 + j*(13) -447 + j*(-110) --76 + j*(316) -42 + j*(71) --20 + j*(-75) --17 + j*(82) --231 + j*(-258) -156 + j*(-174) --85 + j*(-142) --165 + j*(-173) --185 + j*(-25) -173 + j*(137) -303 + j*(-119) --86 + j*(-105) --253 + j*(-318) --68 + j*(142) --213 + j*(259) -179 + j*(-58) --93 + j*(122) -135 + j*(-185) --1 + j*(-180) -261 + j*(-385) --207 + j*(-315) -6 + j*(-70) -216 + j*(339) --137 + j*(-129) -35 + j*(15) -16 + j*(127) -71 + j*(-29) --254 + j*(-211) --325 + j*(103) --222 + j*(6) -159 + j*(91) -25 + j*(106) --139 + j*(101) --133 + j*(-289) --124 + j*(-40) --238 + j*(-183) --144 + j*(-1) -111 + j*(-64) -63 + j*(-308) --78 + j*(-153) -324 + j*(-243) -209 + j*(11) -64 + j*(232) -71 + j*(62) -203 + j*(-52) --161 + j*(129) --339 + j*(144) -78 + j*(86) -66 + j*(-263) --78 + j*(-190) -247 + j*(293) --25 + j*(19) --267 + j*(-15) -89 + j*(-206) --64 + j*(120) -83 + j*(165) --195 + j*(249) --55 + j*(-379) --194 + j*(19) --139 + j*(49) -316 + j*(-139) --190 + j*(170) --33 + j*(34) -14 + j*(-44) --363 + j*(50) -39 + j*(77) -296 + j*(-133) --183 + j*(289) --96 + j*(-81) --74 + j*(-333) -92 + j*(-183) --99 + j*(167) --63 + j*(21) -339 + j*(-39) --175 + j*(-257) -72 + j*(117) --192 + j*(105) -17 + j*(-17) --84 + j*(166) -49 + j*(188) --156 + j*(153) -74 + j*(-169) --35 + j*(280) --81 + j*(101) -9 + j*(112) -214 + j*(-38) -254 + j*(-35) -78 + j*(263) -125 + j*(-71) -100 + j*(68) -339 + j*(111) --10 + j*(134) --4 + j*(-69) --98 + j*(74) --41 + j*(106) --28 + j*(330) -325 + j*(88) --59 + j*(41) --110 + j*(-247) -154 + j*(16) -463 + j*(363) --112 + j*(-29) -133 + j*(-1) -315 + j*(208) --102 + j*(-248) -135 + j*(23) -328 + j*(11) -201 + j*(46) -163 + j*(134) -224 + j*(-62) -178 + j*(-89) -136 + j*(107) -69 + j*(-224) -140 + j*(-87) --112 + j*(254) --65 + j*(120) --239 + j*(-35) -80 + j*(30) --331 + j*(-125) --71 + j*(45) -31 + j*(417) --17 + j*(-139) --54 + j*(49) -246 + j*(-253) --6 + j*(101) -110 + j*(-138) --88 + j*(56) -66 + j*(264) --255 + j*(-18) --155 + j*(95) --332 + j*(88) --103 + j*(25) --618 + j*(214) -213 + j*(-211) -260 + j*(-49) --94 + j*(-75) --9 + j*(12) -97 + j*(171) -74 + j*(219) --18 + j*(-54) -101 + j*(-135) --159 + j*(82) --48 + j*(-196) -408 + j*(275) --194 + j*(-74) -111 + j*(337) --13 + j*(409) --106 + j*(-51) --178 + j*(-203) --228 + j*(-69) --243 + j*(-10) -1 + j*(-8) -177 + j*(-189) -85 + j*(16) -131 + j*(270) --96 + j*(226) --4 + j*(336) --217 + j*(42) --99 + j*(-82) --206 + j*(-93) -18 + j*(295) -99 + j*(-189) --350 + j*(129) --8 + j*(91) -59 + j*(-274) --83 + j*(173) -48 + j*(29) -207 + j*(-75) -49 + j*(78) --65 + j*(-382) -193 + j*(100) --70 + j*(42) -33 + j*(-206) -228 + j*(49) -53 + j*(208) --76 + j*(-93) -102 + j*(-103) --256 + j*(-43) -86 + j*(-13) --111 + j*(40) -186 + j*(-48) --2 + j*(498) --182 + j*(52) --127 + j*(81) -74 + j*(-54) -38 + j*(-88) -35 + j*(-194) --173 + j*(112) --129 + j*(224) --54 + j*(-2) -191 + j*(113) --88 + j*(72) --69 + j*(-259) -84 + j*(240) --187 + j*(70) --79 + j*(-11) -259 + j*(206) -123 + j*(365) -92 + j*(103) --187 + j*(76) -54 + j*(232) -40 + j*(-158) --212 + j*(-424) --91 + j*(215) --112 + j*(138) --110 + j*(243) --110 + j*(145) -72 + j*(80) -30 + j*(-110) -180 + j*(26) -63 + j*(5) -232 + j*(238) -199 + j*(-119) -438 + j*(64) --40 + j*(-139) --146 + j*(-31) -85 + j*(167) -139 + j*(-206) -45 + j*(66) -98 + j*(-75) -23 + j*(131) -131 + j*(15) --84 + j*(126) --64 + j*(-182) -28 + j*(141) -17 + j*(37) -194 + j*(6) --4 + j*(336) -160 + j*(205) --259 + j*(113) --52 + j*(4) --104 + j*(-249) --11 + j*(-245) --66 + j*(86) -30 + j*(-138) -90 + j*(-182) -47 + j*(122) -281 + j*(166) --230 + j*(13) --165 + j*(380) -222 + j*(-15) --247 + j*(113) --91 + j*(-12) --88 + j*(200) --69 + j*(240) --165 + j*(-6) --124 + j*(-184) --327 + j*(296) --209 + j*(37) --114 + j*(-329) -238 + j*(-267) --122 + j*(-149) --104 + j*(-238) -339 + j*(264) -347 + j*(76) -184 + j*(-87) -272 + j*(-118) -10 + j*(169) -23 + j*(74) --53 + j*(377) --180 + j*(-162) --35 + j*(-269) -73 + j*(280) --176 + j*(-9) -69 + j*(172) --14 + j*(101) --124 + j*(-119) --54 + j*(-187) --47 + j*(158) -352 + j*(147) -167 + j*(312) --187 + j*(-197) -101 + j*(202) --170 + j*(-168) -140 + j*(39) -132 + j*(40) -29 + j*(-33) --226 + j*(204) --341 + j*(-25) --21 + j*(235) -110 + j*(25) --176 + j*(40) --35 + j*(105) --175 + j*(13) --85 + j*(-78) --216 + j*(-102) -147 + j*(43) -370 + j*(-45) --330 + j*(-246) --337 + j*(179) --133 + j*(67) -110 + j*(-80) -92 + j*(-27) -199 + j*(-197) -150 + j*(98) --129 + j*(79) --209 + j*(-61) --128 + j*(406) -472 + j*(301) --19 + j*(146) --18 + j*(-83) --54 + j*(-16) -121 + j*(76) --417 + j*(77) --192 + j*(-91) -35 + j*(232) -240 + j*(161) --132 + j*(-16) --149 + j*(72) --26 + j*(-36) --112 + j*(-83) --86 + j*(-100) -83 + j*(-132) --123 + j*(53) --269 + j*(-47) --93 + j*(180) -129 + j*(200) --218 + j*(105) -116 + j*(98) --157 + j*(-165) --252 + j*(-54) -87 + j*(91) -309 + j*(-156) -72 + j*(-159) --16 + j*(-136) --54 + j*(16) --103 + j*(170) -76 + j*(182) --231 + j*(-148) -47 + j*(169) -21 + j*(163) -84 + j*(261) -198 + j*(223) --277 + j*(100) --166 + j*(-125) -125 + j*(-30) --276 + j*(266) -159 + j*(26) -311 + j*(171) --404 + j*(289) --104 + j*(-370) -172 + j*(-347) -59 + j*(-465) --428 + j*(43) -26 + j*(-619) --139 + j*(192) -213 + j*(469) -395 + j*(104) -146 + j*(-270) -77 + j*(257) --204 + j*(245) -61 + j*(264) -317 + j*(351) -395 + j*(379) --250 + j*(-278) -547 + j*(-360) --296 + j*(-69) -71 + j*(260) -456 + j*(-113) -316 + j*(214) -107 + j*(-390) -313 + j*(228) --105 + j*(486) -120 + j*(275) -541 + j*(-306) --351 + j*(-19) --144 + j*(-456) -103 + j*(-197) --262 + j*(-299) -305 + j*(62) --245 + j*(-17) --219 + j*(472) -200 + j*(-195) --155 + j*(-257) --211 + j*(341) -146 + j*(262) --86 + j*(229) --245 + j*(-318) -368 + j*(-296) --375 + j*(305) --582 + j*(149) -412 + j*(-397) -421 + j*(-441) -434 + j*(-191) -141 + j*(325) --331 + j*(88) -610 + j*(43) --328 + j*(305) -351 + j*(-415) -161 + j*(428) -530 + j*(142) --705 + j*(-324) --76 + j*(132) --316 + j*(-183) --307 + j*(187) -148 + j*(361) -183 + j*(94) --168 + j*(360) --266 + j*(129) --301 + j*(-244) --252 + j*(232) --546 + j*(216) --227 + j*(121) --35 + j*(-342) --190 + j*(-325) --59 + j*(523) --171 + j*(-315) -297 + j*(183) -194 + j*(148) --443 + j*(281) --512 + j*(-66) -532 + j*(250) --276 + j*(306) --358 + j*(187) --477 + j*(518) --310 + j*(-158) -167 + j*(-405) -66 + j*(-134) -96 + j*(379) --23 + j*(-460) --404 + j*(-227) --14 + j*(-501) --691 + j*(-200) --339 + j*(30) -648 + j*(317) -347 + j*(-322) --260 + j*(597) --610 + j*(216) -443 + j*(205) -249 + j*(-314) -486 + j*(-170) --298 + j*(87) -141 + j*(238) --60 + j*(-71) -67 + j*(-124) --291 + j*(-540) -174 + j*(-324) --161 + j*(-228) -193 + j*(-37) --153 + j*(-331) -235 + j*(293) --141 + j*(-504) -339 + j*(49) -373 + j*(21) -473 + j*(355) --270 + j*(268) --26 + j*(-260) -379 + j*(-419) -178 + j*(-35) -307 + j*(680) -564 + j*(-397) --474 + j*(-527) -482 + j*(207) -374 + j*(51) -3 + j*(123) -5 + j*(586) -267 + j*(491) -185 + j*(225) -312 + j*(556) -4 + j*(-366) -166 + j*(405) --346 + j*(422) --438 + j*(-416) -390 + j*(-59) -30 + j*(-288) -274 + j*(-242) --114 + j*(-100) --177 + j*(-375) --455 + j*(-292) --272 + j*(301) --218 + j*(-479) -447 + j*(-296) --335 + j*(-378) --427 + j*(-16) -308 + j*(-300) -479 + j*(322) --170 + j*(82) --366 + j*(-153) --701 + j*(-477) --350 + j*(282) --327 + j*(344) --389 + j*(-333) --450 + j*(-218) --3 + j*(682) -260 + j*(-402) -70 + j*(305) -588 + j*(520) --1 + j*(-161) --292 + j*(-104) --267 + j*(434) --195 + j*(404) --435 + j*(542) --376 + j*(-235) --187 + j*(42) -61 + j*(550) --125 + j*(93) --262 + j*(217) -512 + j*(234) -405 + j*(358) -52 + j*(-291) -1 + j*(395) -450 + j*(-216) --172 + j*(432) --180 + j*(-247) -15 + j*(-400) --78 + j*(363) -227 + j*(123) -403 + j*(-133) --124 + j*(258) --400 + j*(-366) -72 + j*(-175) --140 + j*(-51) -90 + j*(-166) --484 + j*(148) --404 + j*(-392) --197 + j*(133) -241 + j*(-45) -122 + j*(-306) --136 + j*(296) --194 + j*(264) -516 + j*(-226) --168 + j*(-320) --14 + j*(-386) -231 + j*(440) -146 + j*(346) -268 + j*(451) -184 + j*(-27) -310 + j*(214) -409 + j*(-258) --361 + j*(-303) -153 + j*(-127) --217 + j*(-438) -107 + j*(476) --204 + j*(403) --313 + j*(315) --328 + j*(-307) --351 + j*(97) -185 + j*(-211) -122 + j*(233) --445 + j*(-503) --212 + j*(-397) --420 + j*(196) -64 + j*(-252) -407 + j*(-336) --265 + j*(280) -281 + j*(-268) -218 + j*(-292) --138 + j*(484) --16 + j*(192) -474 + j*(362) --399 + j*(-2) -73 + j*(-350) -264 + j*(158) -365 + j*(-137) -71 + j*(-62) --389 + j*(-485) --74 + j*(-57) --281 + j*(252) -299 + j*(258) -1 + j*(200) -252 + j*(44) -95 + j*(-210) -180 + j*(-445) --356 + j*(228) -90 + j*(-321) --198 + j*(-281) -441 + j*(-279) --417 + j*(428) --317 + j*(-210) -156 + j*(-520) --59 + j*(-228) -238 + j*(-274) --299 + j*(-308) --270 + j*(-294) --181 + j*(-165) -180 + j*(-48) --172 + j*(-289) -395 + j*(77) -212 + j*(-88) -361 + j*(378) --260 + j*(-753) -205 + j*(-86) --151 + j*(127) -416 + j*(-146) -121 + j*(-566) -65 + j*(-477) -119 + j*(281) -43 + j*(-42) --172 + j*(182) --340 + j*(396) -51 + j*(286) -235 + j*(-410) -296 + j*(-146) --86 + j*(-184) --59 + j*(-322) --381 + j*(236) -98 + j*(-173) --176 + j*(218) --682 + j*(-62) --41 + j*(-211) --525 + j*(-330) -36 + j*(-36) --578 + j*(-367) --245 + j*(380) --305 + j*(301) -333 + j*(-141) --127 + j*(-254) -308 + j*(-378) --358 + j*(177) -231 + j*(216) --112 + j*(459) --436 + j*(-497) -296 + j*(231) --276 + j*(-409) -299 + j*(144) -310 + j*(-267) --309 + j*(-237) --204 + j*(104) -158 + j*(194) -325 + j*(-127) -140 + j*(260) -52 + j*(131) -29 + j*(-135) --162 + j*(345) --5 + j*(132) -69 + j*(-456) -302 + j*(149) -211 + j*(-262) --506 + j*(-175) -292 + j*(182) -52 + j*(-322) -365 + j*(-232) -312 + j*(-269) --319 + j*(21) --315 + j*(-581) --138 + j*(167) --43 + j*(197) --42 + j*(450) --296 + j*(155) --540 + j*(358) --307 + j*(87) --446 + j*(-250) -97 + j*(116) -140 + j*(-486) -300 + j*(-278) --419 + j*(163) --211 + j*(-185) --194 + j*(367) -291 + j*(250) -312 + j*(-236) -195 + j*(81) --465 + j*(-375) -482 + j*(115) -116 + j*(120) -122 + j*(320) --55 + j*(-224) --280 + j*(177) -542 + j*(-264) -416 + j*(103) --152 + j*(-113) --116 + j*(-58) --139 + j*(-262) --165 + j*(-510) --57 + j*(-504) -168 + j*(-228) -474 + j*(-120) --119 + j*(10) -313 + j*(-328) --291 + j*(209) -271 + j*(-57) -358 + j*(-245) -419 + j*(-226) --45 + j*(-529) -344 + j*(-443) -147 + j*(-416) --105 + j*(-279) -40 + j*(4) --409 + j*(212) --322 + j*(-257) --169 + j*(-639) --194 + j*(-323) -311 + j*(-214) --356 + j*(559) -318 + j*(-374) -157 + j*(112) --339 + j*(76) --456 + j*(153) --328 + j*(-325) -504 + j*(113) --447 + j*(219) -173 + j*(284) -194 + j*(-21) --136 + j*(-310) --91 + j*(351) --112 + j*(-317) -474 + j*(227) --348 + j*(124) -368 + j*(-102) -395 + j*(-190) --172 + j*(202) --148 + j*(-287) -393 + j*(-330) -144 + j*(411) --259 + j*(238) -371 + j*(-130) -40 + j*(-457) -129 + j*(-453) --451 + j*(-215) --333 + j*(242) -353 + j*(334) --604 + j*(356) -209 + j*(-318) --358 + j*(-76) --118 + j*(-313) -439 + j*(-315) -60 + j*(-572) --457 + j*(282) --834 + j*(-7) -428 + j*(-140) -325 + j*(215) -42 + j*(263) -301 + j*(151) -140 + j*(-72) -489 + j*(-438) -323 + j*(-402) -194 + j*(-13) -257 + j*(-322) --334 + j*(267) -231 + j*(409) --231 + j*(-271) --265 + j*(394) --324 + j*(-305) --588 + j*(-325) -84 + j*(-489) -366 + j*(43) --291 + j*(108) -533 + j*(-455) --100 + j*(352) -181 + j*(-187) -287 + j*(-428) --322 + j*(17) -90 + j*(-332) -413 + j*(-171) --474 + j*(-153) --167 + j*(-209) -76 + j*(-141) -395 + j*(201) --330 + j*(212) -127 + j*(-255) -120 + j*(-15) --132 + j*(190) --436 + j*(-209) --281 + j*(425) -300 + j*(-408) --162 + j*(-301) --316 + j*(-458) -166 + j*(-491) --384 + j*(-423) -568 + j*(-527) --212 + j*(296) --204 + j*(-298) --229 + j*(117) --159 + j*(-412) -365 + j*(358) -260 + j*(-245) -247 + j*(33) -162 + j*(139) --332 + j*(284) --489 + j*(-540) --221 + j*(-39) --55 + j*(-142) --129 + j*(360) -235 + j*(-252) -513 + j*(104) --58 + j*(-313) -419 + j*(284) --267 + j*(316) -588 + j*(-197) --193 + j*(-361) -370 + j*(556) --269 + j*(106) -153 + j*(-44) --167 + j*(-265) --21 + j*(240) -324 + j*(-368) --233 + j*(-361) --260 + j*(-260) --504 + j*(245) --684 + j*(316) --13 + j*(-153) -89 + j*(-546) -268 + j*(-261) -392 + j*(448) -359 + j*(397) -448 + j*(-398) --400 + j*(-225) --547 + j*(-383) -399 + j*(429) --360 + j*(-187) -36 + j*(-126) --384 + j*(291) -158 + j*(-358) -337 + j*(569) -431 + j*(-49) -581 + j*(30) -158 + j*(-206) -361 + j*(-217) --216 + j*(-233) -309 + j*(-486) -258 + j*(-265) -363 + j*(199) --440 + j*(309) --134 + j*(-397) -441 + j*(298) -356 + j*(285) -148 + j*(-550) -207 + j*(86) -537 + j*(395) --137 + j*(297) --80 + j*(409) -696 + j*(23) -25 + j*(-275) -402 + j*(129) -334 + j*(219) -79 + j*(271) --461 + j*(-98) -21 + j*(-23) --138 + j*(354) -487 + j*(-36) -373 + j*(-1) --540 + j*(-255) -108 + j*(-153) -232 + j*(249) -262 + j*(136) --284 + j*(-388) -254 + j*(-303) -4 + j*(-573) --71 + j*(327) --25 + j*(-76) --33 + j*(-450) -248 + j*(362) -61 + j*(-260) -288 + j*(272) -245 + j*(-42) --204 + j*(277) --479 + j*(-407) --165 + j*(451) -409 + j*(445) --143 + j*(566) --254 + j*(-428) --61 + j*(408) --203 + j*(-141) --38 + j*(893) --53 + j*(235) -170 + j*(-614) -217 + j*(180) -499 + j*(-375) --339 + j*(232) --112 + j*(-235) -290 + j*(233) --400 + j*(214) -470 + j*(363) --634 + j*(-109) --344 + j*(45) -308 + j*(-479) --330 + j*(-6) --141 + j*(-100) --275 + j*(195) -474 + j*(139) -23 + j*(482) --501 + j*(-599) --23 + j*(105) -204 + j*(-323) -220 + j*(119) -471 + j*(-33) --176 + j*(-472) --64 + j*(-11) --98 + j*(158) -94 + j*(-177) --395 + j*(-368) -106 + j*(106) --556 + j*(-269) -404 + j*(389) --13 + j*(-54) --25 + j*(455) -2 + j*(366) -418 + j*(-81) -390 + j*(-341) --173 + j*(-397) -364 + j*(-233) -17 + j*(-495) --489 + j*(86) --287 + j*(419) -93 + j*(431) --31 + j*(212) --218 + j*(-117) --233 + j*(244) -1 + j*(130) --180 + j*(-312) --434 + j*(57) -501 + j*(22) -324 + j*(-359) --497 + j*(-63) -453 + j*(-11) -225 + j*(-460) --413 + j*(-100) --16 + j*(440) -500 + j*(130) --414 + j*(161) -469 + j*(326) -211 + j*(175) -332 + j*(-65) -407 + j*(13) -207 + j*(467) --366 + j*(372) -200 + j*(-223) --301 + j*(-318) --198 + j*(-273) --209 + j*(221) --148 + j*(5) -102 + j*(433) --107 + j*(-116) -303 + j*(337) -356 + j*(98) --203 + j*(369) -452 + j*(281) --542 + j*(421) -54 + j*(371) -222 + j*(-46) -559 + j*(544) -100 + j*(-298) -68 + j*(204) --264 + j*(-267) --97 + j*(-311) --738 + j*(203) -282 + j*(342) --310 + j*(778) --209 + j*(102) -154 + j*(-2) -11 + j*(-8) -153 + j*(222) -4 + j*(-33) -309 + j*(283) --8 + j*(117) --136 + j*(-322) -35 + j*(33) --11 + j*(176) -119 + j*(237) -186 + j*(45) -77 + j*(124) -288 + j*(35) --57 + j*(216) -101 + j*(-8) -119 + j*(-40) -102 + j*(-182) -15 + j*(83) --88 + j*(74) -187 + j*(388) --7 + j*(-26) -284 + j*(-194) -235 + j*(-341) --86 + j*(-122) --98 + j*(-227) --177 + j*(-59) --202 + j*(-35) --58 + j*(-23) --12 + j*(-45) -83 + j*(33) --135 + j*(-110) --112 + j*(-204) --404 + j*(-49) --187 + j*(-67) --158 + j*(168) --105 + j*(-175) -13 + j*(-358) -4 + j*(-224) -35 + j*(-62) -120 + j*(-361) --274 + j*(-179) --63 + j*(23) --110 + j*(-18) --194 + j*(-4) --61 + j*(-28) -138 + j*(-290) -100 + j*(-38) --128 + j*(-204) --246 + j*(-176) -397 + j*(33) -180 + j*(80) --214 + j*(-113) --52 + j*(244) --95 + j*(-3) --87 + j*(-13) -15 + j*(73) -71 + j*(-78) -110 + j*(-1) -4 + j*(-154) -65 + j*(-86) --14 + j*(100) --88 + j*(21) --117 + j*(120) --478 + j*(-64) --50 + j*(-23) -217 + j*(10) --46 + j*(-238) -60 + j*(-23) -235 + j*(-35) --79 + j*(339) --192 + j*(-21) --89 + j*(135) --107 + j*(126) --221 + j*(42) -211 + j*(184) -66 + j*(-160) --168 + j*(-4) --105 + j*(85) -132 + j*(-27) -124 + j*(-130) -174 + j*(-112) -151 + j*(76) -249 + j*(-163) -72 + j*(233) --243 + j*(-77) --294 + j*(-25) --281 + j*(61) -112 + j*(67) --37 + j*(13) -74 + j*(-144) --168 + j*(-35) --13 + j*(-313) --386 + j*(10) --311 + j*(-79) --11 + j*(90) -185 + j*(405) -186 + j*(-17) --127 + j*(-137) -10 + j*(136) --59 + j*(110) -1 + j*(-83) --20 + j*(-180) -214 + j*(361) -231 + j*(62) --104 + j*(-86) --192 + j*(185) --108 + j*(170) --169 + j*(-192) --104 + j*(-171) --28 + j*(-57) --208 + j*(126) -185 + j*(-78) -105 + j*(159) --228 + j*(-110) -340 + j*(82) -235 + j*(214) --80 + j*(-14) -234 + j*(-162) --131 + j*(63) --43 + j*(60) --157 + j*(68) --207 + j*(144) --77 + j*(53) -214 + j*(147) --150 + j*(-83) --100 + j*(90) --43 + j*(90) -97 + j*(129) --34 + j*(-44) -14 + j*(86) --258 + j*(47) -161 + j*(38) -286 + j*(-1) -113 + j*(178) --124 + j*(-255) --3 + j*(347) -136 + j*(-137) -62 + j*(-89) -36 + j*(267) --74 + j*(-311) --1 + j*(109) -96 + j*(-269) -223 + j*(-111) -298 + j*(-105) --149 + j*(9) --303 + j*(36) --265 + j*(276) --324 + j*(-81) --176 + j*(-8) -243 + j*(311) --18 + j*(-35) --212 + j*(177) --35 + j*(158) -20 + j*(121) -70 + j*(64) --201 + j*(-1) --76 + j*(258) --252 + j*(101) -2 + j*(225) -92 + j*(-81) -123 + j*(-123) --125 + j*(78) -146 + j*(-37) -184 + j*(375) -62 + j*(102) --294 + j*(196) --3 + j*(217) --214 + j*(322) -559 + j*(98) --136 + j*(173) -47 + j*(-37) -98 + j*(-22) -234 + j*(-21) -36 + j*(-142) -239 + j*(-272) --58 + j*(198) -390 + j*(37) --132 + j*(-216) --95 + j*(-52) -27 + j*(-119) --8 + j*(143) -122 + j*(110) -145 + j*(-146) -210 + j*(-166) --73 + j*(-25) -136 + j*(45) -150 + j*(-169) -45 + j*(-17) -122 + j*(-30) -110 + j*(-110) -63 + j*(-232) -330 + j*(312) --204 + j*(-26) -204 + j*(129) --87 + j*(88) -240 + j*(73) -129 + j*(-101) --68 + j*(92) -115 + j*(122) -273 + j*(103) --320 + j*(-144) -79 + j*(93) --335 + j*(242) -308 + j*(1) -52 + j*(119) -206 + j*(-37) -106 + j*(-74) --288 + j*(-274) --131 + j*(194) --107 + j*(-123) --418 + j*(120) -165 + j*(74) -209 + j*(27) -143 + j*(-276) -12 + j*(-70) -33 + j*(-74) --44 + j*(-145) -1 + j*(-385) -7 + j*(45) -460 + j*(-204) -53 + j*(266) --216 + j*(-86) -28 + j*(92) -118 + j*(61) -168 + j*(-52) -110 + j*(198) -121 + j*(-107) -98 + j*(75) --211 + j*(338) -16 + j*(-6) --261 + j*(346) -101 + j*(-113) --151 + j*(104) --111 + j*(-175) -38 + j*(172) -83 + j*(-206) -173 + j*(199) --34 + j*(66) --12 + j*(-31) -40 + j*(47) -30 + j*(336) -276 + j*(16) -238 + j*(76) -439 + j*(259) -120 + j*(-16) -125 + j*(37) -139 + j*(104) --79 + j*(-187) --431 + j*(219) --304 + j*(-148) --4 + j*(-105) --141 + j*(-92) -194 + j*(-172) --30 + j*(-248) --45 + j*(157) --4 + j*(109) -170 + j*(193) -153 + j*(-243) --304 + j*(-82) -92 + j*(64) -76 + j*(16) -68 + j*(46) --146 + j*(144) -219 + j*(222) --216 + j*(68) --88 + j*(-248) --170 + j*(42) -79 + j*(-355) -43 + j*(67) -69 + j*(33) --137 + j*(-228) -72 + j*(132) --40 + j*(-29) --1 + j*(107) --73 + j*(333) -285 + j*(-302) -252 + j*(-49) -74 + j*(-91) --83 + j*(156) --304 + j*(321) -100 + j*(-276) --182 + j*(-174) --49 + j*(-325) -78 + j*(-262) --262 + j*(-26) -134 + j*(83) --112 + j*(83) -7 + j*(65) --11 + j*(110) -115 + j*(47) --45 + j*(-115) -1 + j*(-168) --112 + j*(-49) --293 + j*(28) --351 + j*(-62) --10 + j*(27) -226 + j*(-30) --57 + j*(176) -37 + j*(-181) -172 + j*(143) -187 + j*(248) --205 + j*(1) -187 + j*(-23) --280 + j*(-25) -200 + j*(-519) --30 + j*(218) --90 + j*(220) --58 + j*(22) -110 + j*(-327) --165 + j*(30) --2 + j*(-261) -222 + j*(-47) --115 + j*(-274) -284 + j*(65) -166 + j*(339) --2 + j*(192) --54 + j*(-168) -139 + j*(-147) -202 + j*(-148) --88 + j*(-42) --88 + j*(87) --16 + j*(-157) --116 + j*(-215) -254 + j*(57) --135 + j*(-27) -82 + j*(223) --165 + j*(206) -29 + j*(-119) --112 + j*(-28) -241 + j*(330) --164 + j*(-91) --162 + j*(-92) -39 + j*(57) --105 + j*(240) --96 + j*(-112) -266 + j*(274) -272 + j*(-71) --81 + j*(79) -100 + j*(-11) --52 + j*(-24) -325 + j*(-252) --24 + j*(363) -170 + j*(-103) --224 + j*(263) -229 + j*(123) -62 + j*(-281) --139 + j*(-92) --103 + j*(124) -387 + j*(-151) -103 + j*(252) --52 + j*(-88) -150 + j*(-183) --508 + j*(47) -16 + j*(-13) -40 + j*(104) --18 + j*(-61) -436 + j*(25) --60 + j*(-131) -165 + j*(101) -220 + j*(191) --254 + j*(-140) -21 + j*(-212) --81 + j*(-122) --252 + j*(-175) -11 + j*(124) --47 + j*(38) -163 + j*(227) --525 + j*(30) -117 + j*(453) --137 + j*(-71) -136 + j*(34) -127 + j*(26) --360 + j*(-185) -247 + j*(-28) --350 + j*(317) --262 + j*(151) -58 + j*(-221) --10 + j*(156) --387 + j*(64) --25 + j*(223) --42 + j*(110) -33 + j*(378) -35 + j*(90) --264 + j*(78) --112 + j*(109) -123 + j*(68) -276 + j*(-239) --11 + j*(-231) -416 + j*(23) -276 + j*(196) --52 + j*(-30) --125 + j*(6) -297 + j*(47) -186 + j*(-114) -75 + j*(-99) -379 + j*(1) --25 + j*(330) --81 + j*(-228) --118 + j*(-213) --45 + j*(-100) --372 + j*(84) --93 + j*(-155) --169 + j*(-9) -245 + j*(-222) --134 + j*(-5) --188 + j*(303) --162 + j*(-185) -132 + j*(-141) --325 + j*(301) --42 + j*(-164) -256 + j*(151) -52 + j*(69) --128 + j*(325) --165 + j*(134) --162 + j*(-32) --117 + j*(-190) -17 + j*(-82) -173 + j*(-173) -298 + j*(-11) --151 + j*(141) --327 + j*(147) --62 + j*(72) --21 + j*(-19) --10 + j*(-189) --36 + j*(50) -95 + j*(-60) -122 + j*(141) -125 + j*(23) -18 + j*(218) --36 + j*(288) --127 + j*(81) -21 + j*(-100) --216 + j*(-237) -85 + j*(-117) -4 + j*(-219) -260 + j*(-119) -154 + j*(132) --110 + j*(312) --231 + j*(91) -269 + j*(65) --62 + j*(-256) --133 + j*(-183) -84 + j*(-89) -143 + j*(-9) --245 + j*(11) --196 + j*(-218) -85 + j*(-211) --146 + j*(91) --179 + j*(-57) --122 + j*(-66) --112 + j*(45) --354 + j*(-65) -101 + j*(-99) -362 + j*(243) --141 + j*(-321) -210 + j*(114) -127 + j*(223) -257 + j*(-35) --298 + j*(63) --88 + j*(397) --272 + j*(72) -44 + j*(387) --170 + j*(-21) -60 + j*(104) --310 + j*(-85) --327 + j*(213) -326 + j*(-179) --96 + j*(-5) -15 + j*(-286) --76 + j*(27) -103 + j*(124) -5 + j*(-456) --133 + j*(-173) --7 + j*(-293) --62 + j*(-57) -93 + j*(-42) -282 + j*(-146) -133 + j*(252) --98 + j*(63) -14 + j*(138) --192 + j*(108) -100 + j*(216) --214 + j*(-267) -287 + j*(-177) -138 + j*(-223) --74 + j*(92) -210 + j*(134) --143 + j*(40) -119 + j*(-45) -115 + j*(30) -344 + j*(-255) -175 + j*(116) --238 + j*(98) --122 + j*(-103) --223 + j*(378) -213 + j*(103) -23 + j*(163) --150 + j*(130) -116 + j*(257) --257 + j*(-51) --151 + j*(-144) -98 + j*(-243) --285 + j*(-140) -171 + j*(347) -66 + j*(-49) -294 + j*(-273) --100 + j*(-174) --237 + j*(-134) --459 + j*(320) --73 + j*(2) -162 + j*(180) -64 + j*(-307) -263 + j*(-46) --95 + j*(-274) --50 + j*(103) -191 + j*(170) --107 + j*(60) -42 + j*(-159) --35 + j*(-46) --72 + j*(91) -341 + j*(-216) -112 + j*(249) --114 + j*(-213) -11 + j*(71) --42 + j*(-106) --70 + j*(-117) --204 + j*(-8) --30 + j*(59) --257 + j*(263) -190 + j*(-417) --6 + j*(152) --127 + j*(97) --64 + j*(99) --428 + j*(144) --178 + j*(-112) -539 + j*(-2) -338 + j*(-120) -108 + j*(-235) --324 + j*(-28) -16 + j*(160) -70 + j*(188) -11 + j*(73) --49 + j*(-291) -206 + j*(197) -237 + j*(136) -83 + j*(216) -54 + j*(-149) --28 + j*(-105) --37 + j*(-55) -132 + j*(-138) -138 + j*(-161) -55 + j*(-45) --99 + j*(168) -173 + j*(175) -7 + j*(49) --8 + j*(55) -93 + j*(248) -16 + j*(-199) --104 + j*(324) --163 + j*(122) -66 + j*(112) -134 + j*(-49) -25 + j*(-253) --76 + j*(-95) -42 + j*(245) -151 + j*(-187) --153 + j*(-282) -39 + j*(-135) -4 + j*(-163) -75 + j*(190) --126 + j*(-10) -171 + j*(55) --3 + j*(-19) --59 + j*(76) --189 + j*(-52) -125 + j*(-81) -254 + j*(-258) -25 + j*(-116) --359 + j*(333) --127 + j*(110) --243 + j*(156) -184 + j*(33) --265 + j*(5) --120 + j*(4) --265 + j*(-8) -168 + j*(-161) -65 + j*(125) --62 + j*(-164) --208 + j*(-21) --142 + j*(-322) --378 + j*(19) --73 + j*(76) --61 + j*(151) --141 + j*(-202) -132 + j*(133) -228 + j*(-25) -458 + j*(-65) --133 + j*(-45) --233 + j*(85) -126 + j*(-35) -81 + j*(-158) -239 + j*(64) -169 + j*(179) -23 + j*(318) --153 + j*(-144) -92 + j*(-21) -3 + j*(197) -31 + j*(52) -74 + j*(-50) -117 + j*(-38) --108 + j*(-49) -129 + j*(-19) --218 + j*(-81) -123 + j*(-25) -326 + j*(-124) --146 + j*(-104) --19 + j*(-156) --30 + j*(-185) -52 + j*(86) --529 + j*(6) -194 + j*(-97) -109 + j*(278) --315 + j*(-296) -241 + j*(168) -107 + j*(228) --103 + j*(219) -79 + j*(238) -91 + j*(-158) -343 + j*(-144) --165 + j*(-165) --375 + j*(49) -257 + j*(-81) -223 + j*(160) --144 + j*(-144) --11 + j*(252) -70 + j*(-40) -40 + j*(79) -400 + j*(191) -8 + j*(-76) --98 + j*(-105) -8 + j*(33) --69 + j*(-42) -270 + j*(-35) -23 + j*(22) --418 + j*(-221) --38 + j*(-53) -28 + j*(64) -114 + j*(291) -421 + j*(272) --222 + j*(250) --34 + j*(83) -119 + j*(-148) --141 + j*(136) --165 + j*(40) -110 + j*(-94) --341 + j*(105) --62 + j*(25) --187 + j*(107) --132 + j*(221) --17 + j*(1) -279 + j*(-247) -81 + j*(148) -46 + j*(116) --448 + j*(-277) --310 + j*(431) -30 + j*(28) -136 + j*(-87) -8 + j*(24) -257 + j*(-246) --8 + j*(165) --49 + j*(-32) --11 + j*(-11) -34 + j*(-10) --53 + j*(21) -361 + j*(103) --284 + j*(-36) --202 + j*(-190) -62 + j*(88) --69 + j*(190) --66 + j*(-338) -54 + j*(31) --71 + j*(105) --177 + j*(-55) -235 + j*(-53) -28 + j*(104) --363 + j*(80) -144 + j*(2) -250 + j*(192) --60 + j*(1) --206 + j*(-163) -54 + j*(-66) --91 + j*(-169) --78 + j*(-36) -91 + j*(-15) --30 + j*(107) -85 + j*(14) --285 + j*(21) -179 + j*(152) --197 + j*(-69) -86 + j*(-214) -200 + j*(158) -29 + j*(153) --181 + j*(-278) --89 + j*(-222) --172 + j*(-129) --30 + j*(272) -365 + j*(-10) --40 + j*(-85) --8 + j*(-57) --241 + j*(-301) --267 + j*(-530) -38 + j*(-85) --91 + j*(478) --18 + j*(-260) --261 + j*(-103) -41 + j*(69) -376 + j*(74) -59 + j*(342) --450 + j*(-386) --185 + j*(-6) -399 + j*(284) -69 + j*(128) --247 + j*(-365) -88 + j*(-74) -182 + j*(16) --257 + j*(209) --336 + j*(26) --260 + j*(-74) -80 + j*(66) --257 + j*(-243) -139 + j*(-35) --354 + j*(33) -21 + j*(-107) --279 + j*(46) --124 + j*(192) --474 + j*(-165) -61 + j*(-238) --114 + j*(182) --122 + j*(-105) --265 + j*(192) -209 + j*(-58) -134 + j*(-87) --124 + j*(-299) --112 + j*(196) -132 + j*(38) --180 + j*(303) --203 + j*(82) --62 + j*(-222) -37 + j*(371) -128 + j*(148) -194 + j*(198) -11 + j*(-93) -23 + j*(-392) --9 + j*(213) -284 + j*(-231) -108 + j*(-115) --86 + j*(-54) --78 + j*(25) --66 + j*(-118) -139 + j*(-135) -95 + j*(-66) --155 + j*(-134) --136 + j*(13) -37 + j*(147) -105 + j*(-52) -124 + j*(180) -93 + j*(129) -85 + j*(233) -139 + j*(-129) -363 + j*(93) -110 + j*(181) -321 + j*(-131) --116 + j*(-50) -292 + j*(52) -130 + j*(-219) --76 + j*(155) -170 + j*(8) --60 + j*(36) -105 + j*(58) -368 + j*(125) --136 + j*(-108) --142 + j*(69) -21 + j*(-49) -10 + j*(-94) --196 + j*(-4) -488 + j*(313) -86 + j*(-116) -167 + j*(34) --52 + j*(267) --132 + j*(273) --107 + j*(-311) -12 + j*(-185) -148 + j*(-227) --175 + j*(-88) -68 + j*(40) -44 + j*(-27) -158 + j*(-191) --6 + j*(122) -315 + j*(-21) --213 + j*(59) -421 + j*(-175) --81 + j*(275) --93 + j*(80) --29 + j*(-130) --58 + j*(153) --246 + j*(-158) -71 + j*(-250) --354 + j*(120) -37 + j*(195) -460 + j*(-35) --176 + j*(-60) -109 + j*(30) --274 + j*(46) -163 + j*(-293) -339 + j*(124) --288 + j*(103) -256 + j*(-101) --62 + j*(173) --130 + j*(288) -137 + j*(-49) -169 + j*(-1) --69 + j*(-170) --231 + j*(207) -165 + j*(62) --147 + j*(102) --28 + j*(158) --18 + j*(-250) -58 + j*(-124) --211 + j*(-76) --277 + j*(-126) --288 + j*(281) --47 + j*(91) -57 + j*(-258) -158 + j*(31) -173 + j*(-93) -64 + j*(-301) --178 + j*(88) --129 + j*(518) -144 + j*(-270) -146 + j*(-278) -239 + j*(122) -274 + j*(8) -77 + j*(-119) --47 + j*(-154) --2 + j*(219) --204 + j*(267) -118 + j*(166) -42 + j*(-456) --47 + j*(29) --187 + j*(180) --112 + j*(230) -95 + j*(-22) -120 + j*(381) -244 + j*(-168) --9 + j*(103) -143 + j*(97) --337 + j*(1) -228 + j*(18) --43 + j*(92) --42 + j*(6) --16 + j*(483) -35 + j*(257) -100 + j*(-82) -245 + j*(144) -136 + j*(-35) -167 + j*(31) --45 + j*(129) --165 + j*(130) -431 + j*(227) --163 + j*(-289) -157 + j*(-82) -371 + j*(-184) -8 + j*(117) --247 + j*(-31) -57 + j*(120) --107 + j*(-310) --71 + j*(-28) --234 + j*(-110) --88 + j*(80) --275 + j*(75) --202 + j*(311) --124 + j*(-170) -1 + j*(-284) --44 + j*(-331) --148 + j*(-53) --11 + j*(8) -156 + j*(255) -302 + j*(170) --139 + j*(47) -50 + j*(146) --132 + j*(234) --40 + j*(0) -31 + j*(-148) --151 + j*(64) -202 + j*(-64) -207 + j*(42) --194 + j*(48) -100 + j*(-102) -97 + j*(123) -262 + j*(82) --321 + j*(-168) --282 + j*(19) --35 + j*(201) -257 + j*(114) --47 + j*(-174) --59 + j*(-81) -1 + j*(-50) --180 + j*(-216) --141 + j*(-33) --106 + j*(167) -14 + j*(62) -151 + j*(104) --206 + j*(-145) -132 + j*(-35) --2 + j*(94) -107 + j*(101) -65 + j*(93) -30 + j*(-250) -175 + j*(159) -16 + j*(202) --87 + j*(-223) -7 + j*(-244) -58 + j*(-51) -103 + j*(-135) --168 + j*(-313) --325 + j*(132) --136 + j*(-111) --211 + j*(-162) -35 + j*(-76) -354 + j*(196) -132 + j*(-28) --12 + j*(-352) -140 + j*(-337) --144 + j*(-102) --115 + j*(-63) --36 + j*(65) --98 + j*(-89) --119 + j*(53) -91 + j*(-206) -51 + j*(-476) -160 + j*(-76) --222 + j*(-345) --265 + j*(202) -86 + j*(-40) -142 + j*(170) -115 + j*(237) -187 + j*(-6) --32 + j*(-87) --379 + j*(175) --46 + j*(-578) --116 + j*(-57) -30 + j*(19) --80 + j*(115) -13 + j*(100) --116 + j*(121) -30 + j*(237) --226 + j*(165) --220 + j*(-202) -70 + j*(-153) --282 + j*(-106) --322 + j*(-4) --46 + j*(7) -176 + j*(41) -195 + j*(132) --103 + j*(23) --114 + j*(-115) -153 + j*(317) --57 + j*(60) --160 + j*(-151) --236 + j*(167) -203 + j*(-55) --18 + j*(7) --244 + j*(-16) -250 + j*(159) -3 + j*(-170) --54 + j*(33) --42 + j*(-67) -334 + j*(149) --354 + j*(85) --4 + j*(-64) --63 + j*(92) -223 + j*(-244) -4 + j*(-47) -125 + j*(-204) -107 + j*(70) -191 + j*(-337) --331 + j*(185) --441 + j*(74) --96 + j*(178) --70 + j*(83) -152 + j*(100) --117 + j*(371) -184 + j*(-202) --223 + j*(200) --42 + j*(-50) -18 + j*(126) -20 + j*(-46) --298 + j*(203) -46 + j*(146) --153 + j*(-19) -268 + j*(-62) -103 + j*(-322) -157 + j*(694) --23 + j*(105) --129 + j*(183) --28 + j*(132) -21 + j*(37) -30 + j*(173) --101 + j*(121) --100 + j*(189) --272 + j*(-186) -211 + j*(-85) --222 + j*(-71) --218 + j*(-44) --98 + j*(38) -88 + j*(113) -249 + j*(-197) -86 + j*(346) --49 + j*(-60) -235 + j*(230) -62 + j*(-8) --169 + j*(-186) -304 + j*(-342) -119 + j*(65) -34 + j*(-357) -125 + j*(-96) --258 + j*(103) -71 + j*(-79) --179 + j*(193) --139 + j*(-187) --236 + j*(-131) -408 + j*(340) -139 + j*(-67) --29 + j*(21) --59 + j*(99) --19 + j*(-37) -377 + j*(107) --272 + j*(164) -81 + j*(-98) --44 + j*(-69) --203 + j*(-243) --63 + j*(116) --82 + j*(13) --4 + j*(-42) -83 + j*(-158) --216 + j*(-180) --112 + j*(112) --232 + j*(-168) -146 + j*(169) --199 + j*(55) -74 + j*(-52) --69 + j*(-372) --64 + j*(-177) --92 + j*(-14) -1 + j*(-285) --81 + j*(-277) -57 + j*(-180) --185 + j*(-419) --235 + j*(-25) --298 + j*(117) --20 + j*(82) -110 + j*(231) -20 + j*(-115) -223 + j*(71) --54 + j*(18) --82 + j*(-61) --54 + j*(88) -112 + j*(-132) --216 + j*(-183) -144 + j*(135) --95 + j*(361) -126 + j*(194) -4 + j*(-424) -185 + j*(91) --4 + j*(-30) --112 + j*(-177) --479 + j*(195) --301 + j*(-36) --324 + j*(74) -66 + j*(20) --174 + j*(-128) -57 + j*(-160) -1 + j*(-95) -121 + j*(-1) -78 + j*(-13) -8 + j*(-64) --83 + j*(46) --59 + j*(-35) -7 + j*(23) --100 + j*(168) --151 + j*(-72) --171 + j*(-166) -124 + j*(396) --94 + j*(-126) -136 + j*(-111) --80 + j*(-441) -136 + j*(268) -358 + j*(69) -11 + j*(-5) --298 + j*(-37) --37 + j*(144) --185 + j*(4) --16 + j*(282) --12 + j*(-115) --4 + j*(-86) -29 + j*(-469) --443 + j*(-96) --258 + j*(7) -115 + j*(-133) --213 + j*(-262) -279 + j*(-81) -129 + j*(-107) --167 + j*(38) --91 + j*(-312) --202 + j*(335) -262 + j*(37) -1 + j*(-13) -135 + j*(319) -127 + j*(297) -130 + j*(115) --280 + j*(151) --213 + j*(-125) --90 + j*(23) -110 + j*(192) --148 + j*(-175) --91 + j*(-89) -428 + j*(-33) -122 + j*(-108) -206 + j*(-93) --56 + j*(-170) -330 + j*(-283) -243 + j*(18) -257 + j*(-235) -95 + j*(-140) --50 + j*(-323) --146 + j*(214) -167 + j*(229) --22 + j*(23) -72 + j*(-136) -265 + j*(-286) --305 + j*(-121) -6 + j*(165) -124 + j*(-304) -184 + j*(78) -360 + j*(8) --103 + j*(-96) -99 + j*(-48) --266 + j*(145) -206 + j*(-59) -313 + j*(58) --79 + j*(-182) -109 + j*(91) --360 + j*(-320) -153 + j*(227) --165 + j*(87) -34 + j*(-18) -3 + j*(229) -1 + j*(49) -245 + j*(140) --162 + j*(89) --110 + j*(-125) --93 + j*(202) -109 + j*(-93) -90 + j*(-56) -358 + j*(151) -286 + j*(-158) -182 + j*(-62) --204 + j*(49) -20 + j*(279) --105 + j*(-283) --83 + j*(43) --13 + j*(-51) --68 + j*(176) --152 + j*(-12) --129 + j*(231) -9 + j*(143) -102 + j*(-153) --134 + j*(-113) -34 + j*(174) --151 + j*(180) --45 + j*(-171) -206 + j*(-89) -154 + j*(144) --146 + j*(-276) -216 + j*(57) -495 + j*(30) --177 + j*(25) -97 + j*(240) --84 + j*(-176) --194 + j*(-102) -33 + j*(-204) -181 + j*(-70) --52 + j*(280) -47 + j*(64) --77 + j*(67) -408 + j*(27) -171 + j*(74) --318 + j*(177) -98 + j*(136) --166 + j*(124) -21 + j*(223) --105 + j*(143) --185 + j*(162) -11 + j*(6) -218 + j*(118) --149 + j*(190) -42 + j*(121) --117 + j*(100) --86 + j*(32) -13 + j*(-127) -13 + j*(-260) -102 + j*(49) -173 + j*(210) -110 + j*(-64) --13 + j*(329) -145 + j*(-61) -44 + j*(-65) --110 + j*(-280) -226 + j*(-64) -207 + j*(205) --9 + j*(-98) --291 + j*(-194) -59 + j*(129) --104 + j*(-78) -13 + j*(-115) -2 + j*(-84) -47 + j*(-117) --182 + j*(-156) -371 + j*(66) --185 + j*(249) --360 + j*(-141) -74 + j*(-243) -150 + j*(412) -293 + j*(13) -161 + j*(-319) --52 + j*(250) --81 + j*(-110) -35 + j*(25) -62 + j*(146) --134 + j*(-8) --101 + j*(64) --213 + j*(206) -49 + j*(27) --9 + j*(44) --30 + j*(57) --185 + j*(-103) --175 + j*(-29) --315 + j*(127) -294 + j*(-68) --98 + j*(390) -76 + j*(-11) -216 + j*(272) --136 + j*(5) -44 + j*(210) --3 + j*(-24) -182 + j*(-110) --61 + j*(40) --28 + j*(52) --95 + j*(-206) --57 + j*(230) -182 + j*(-40) -128 + j*(-143) -102 + j*(-54) --83 + j*(28) --37 + j*(-208) --220 + j*(183) -158 + j*(-382) -88 + j*(-19) --25 + j*(-37) -75 + j*(60) --63 + j*(-173) --230 + j*(-128) -112 + j*(-43) --158 + j*(-47) -20 + j*(49) --145 + j*(71) --297 + j*(68) --329 + j*(-21) -245 + j*(-95) --303 + j*(88) --72 + j*(151) --126 + j*(-173) -11 + j*(199) -127 + j*(423) -213 + j*(-18) -230 + j*(17) --110 + j*(-47) -347 + j*(166) -165 + j*(46) --402 + j*(100) --34 + j*(-164) -18 + j*(187) --27 + j*(102) -100 + j*(324) --43 + j*(-269) -118 + j*(-268) --69 + j*(187) -192 + j*(-211) -99 + j*(-127) -262 + j*(42) --93 + j*(-35) --245 + j*(-249) --39 + j*(-274) -115 + j*(-197) -179 + j*(8) -395 + j*(33) -324 + j*(-6) --129 + j*(105) -72 + j*(-66) --239 + j*(-16) --112 + j*(189) --334 + j*(-83) -91 + j*(235) --139 + j*(91) --136 + j*(122) -47 + j*(-132) -453 + j*(-16) --150 + j*(-126) --255 + j*(86) -146 + j*(-169) --31 + j*(158) -98 + j*(132) --260 + j*(86) --20 + j*(145) -77 + j*(-175) --227 + j*(271) --25 + j*(115) -76 + j*(267) --192 + j*(66) --274 + j*(-34) --163 + j*(-132) --155 + j*(-195) -91 + j*(46) --137 + j*(-191) --151 + j*(260) --8 + j*(29) --83 + j*(25) -17 + j*(-16) --430 + j*(494) -212 + j*(55) -134 + j*(86) -188 + j*(-2) --11 + j*(151) -209 + j*(27) --37 + j*(40) --202 + j*(90) --25 + j*(327) -81 + j*(-401) --180 + j*(194) --146 + j*(262) -221 + j*(87) -280 + j*(-118) --30 + j*(15) -164 + j*(91) -45 + j*(-315) --325 + j*(43) --283 + j*(-286) --63 + j*(-174) --220 + j*(-100) -190 + j*(-108) -37 + j*(-11) -148 + j*(-88) --103 + j*(-93) -122 + j*(94) --124 + j*(-273) --59 + j*(-193) -13 + j*(77) -3 + j*(-186) -36 + j*(-62) --219 + j*(232) -103 + j*(71) -54 + j*(47) -13 + j*(52) --356 + j*(119) --124 + j*(152) -77 + j*(33) --83 + j*(148) --40 + j*(-25) -35 + j*(-64) --170 + j*(-244) --301 + j*(-208) --61 + j*(140) --197 + j*(-47) --134 + j*(-243) -34 + j*(269) --169 + j*(-330) -65 + j*(46) -167 + j*(47) --118 + j*(-40) -65 + j*(-15) --16 + j*(211) --63 + j*(107) -50 + j*(120) --194 + j*(9) --97 + j*(90) --226 + j*(-82) -59 + j*(-375) -123 + j*(-107) -112 + j*(63) --95 + j*(146) --209 + j*(91) -278 + j*(-85) -190 + j*(134) -296 + j*(-10) --175 + j*(-175) -136 + j*(-52) -166 + j*(-25) -129 + j*(107) --254 + j*(-54) -132 + j*(6) -137 + j*(95) --457 + j*(-166) --146 + j*(34) --46 + j*(-144) -32 + j*(291) -143 + j*(168) -108 + j*(14) -25 + j*(-109) --262 + j*(148) --111 + j*(-62) -170 + j*(-84) --148 + j*(217) --279 + j*(-161) --50 + j*(-172) -261 + j*(-89) --186 + j*(31) --35 + j*(201) --392 + j*(-57) --43 + j*(291) --125 + j*(65) -157 + j*(-12) --43 + j*(40) -173 + j*(-97) -231 + j*(-39) -40 + j*(-25) --184 + j*(-57) -31 + j*(-173) --262 + j*(74) -6 + j*(214) -37 + j*(-114) --296 + j*(-238) -115 + j*(-8) -17 + j*(-50) --165 + j*(134) --115 + j*(127) --419 + j*(-182) --29 + j*(-102) -49 + j*(348) --173 + j*(-4) --431 + j*(31) --60 + j*(21) --130 + j*(-76) --278 + j*(-74) --156 + j*(-45) -383 + j*(187) -241 + j*(-255) -105 + j*(-116) --6 + j*(-184) -327 + j*(-173) --32 + j*(39) -23 + j*(78) -35 + j*(0) -116 + j*(-264) --10 + j*(-5) --44 + j*(110) --103 + j*(-112) --506 + j*(227) -144 + j*(-71) -150 + j*(43) -45 + j*(344) --286 + j*(-126) -24 + j*(-301) --136 + j*(-288) -23 + j*(-66) --247 + j*(-122) -2 + j*(-254) --434 + j*(-101) --262 + j*(86) --265 + j*(-110) --293 + j*(115) --11 + j*(361) -249 + j*(-121) --88 + j*(35) --232 + j*(-86) -296 + j*(8) --125 + j*(4) --14 + j*(-228) --212 + j*(259) -30 + j*(207) -165 + j*(-69) -454 + j*(0) --282 + j*(71) -41 + j*(-194) -264 + j*(-13) --313 + j*(129) -82 + j*(106) -76 + j*(-2) -245 + j*(-102) --92 + j*(245) -242 + j*(-47) --132 + j*(-83) -231 + j*(-56) --64 + j*(-59) --94 + j*(-115) -241 + j*(154) --261 + j*(-173) --56 + j*(157) --54 + j*(-21) --180 + j*(28) -144 + j*(104) -64 + j*(23) --93 + j*(-354) -189 + j*(185) --110 + j*(-22) -209 + j*(-222) -79 + j*(-39) -217 + j*(-105) --21 + j*(-139) -91 + j*(205) -195 + j*(-93) --6 + j*(-144) --231 + j*(117) --18 + j*(-35) -87 + j*(190) -152 + j*(56) -248 + j*(66) --3 + j*(-235) --81 + j*(132) --59 + j*(315) --289 + j*(142) -100 + j*(-118) --191 + j*(355) -52 + j*(-271) -1 + j*(-161) --151 + j*(-81) -198 + j*(357) --202 + j*(-13) -19 + j*(-220) -188 + j*(-258) -90 + j*(105) --168 + j*(25) -37 + j*(-505) -281 + j*(-93) --241 + j*(-156) -49 + j*(-28) -16 + j*(-299) -151 + j*(-229) --42 + j*(136) --228 + j*(43) --124 + j*(148) --7 + j*(19) -250 + j*(-66) -207 + j*(118) -80 + j*(28) --22 + j*(61) -190 + j*(-61) -206 + j*(-161) -27 + j*(-344) --176 + j*(-18) -233 + j*(-76) -64 + j*(-87) -334 + j*(-81) -216 + j*(-3) -1 + j*(499) -57 + j*(-66) --123 + j*(-246) --329 + j*(-81) --113 + j*(-94) -41 + j*(204) --194 + j*(-10) --52 + j*(116) --80 + j*(33) --271 + j*(-388) --288 + j*(-45) --65 + j*(-40) -118 + j*(-59) -296 + j*(-220) --175 + j*(57) -4 + j*(71) --124 + j*(62) -153 + j*(95) -209 + j*(209) -132 + j*(293) --72 + j*(-90) -378 + j*(3) -57 + j*(266) --354 + j*(42) -84 + j*(-270) --52 + j*(303) -211 + j*(-53) -132 + j*(-156) -375 + j*(37) --21 + j*(87) -381 + j*(-107) -86 + j*(-33) -98 + j*(21) --189 + j*(-212) --138 + j*(-247) -330 + j*(-127) -34 + j*(-63) -181 + j*(139) --86 + j*(144) -206 + j*(-378) -165 + j*(29) --133 + j*(183) -52 + j*(-56) --140 + j*(123) --123 + j*(68) --13 + j*(243) --144 + j*(-129) --265 + j*(-195) -148 + j*(139) -117 + j*(-42) --105 + j*(-67) --64 + j*(-123) -20 + j*(-232) --250 + j*(85) --117 + j*(-41) --474 + j*(269) -76 + j*(-93) -23 + j*(-175) --138 + j*(191) -13 + j*(-97) -15 + j*(395) -71 + j*(56) --91 + j*(74) --180 + j*(134) --23 + j*(90) -110 + j*(313) --309 + j*(-167) -13 + j*(44) -146 + j*(276) -105 + j*(-266) --9 + j*(-158) -69 + j*(-4) --45 + j*(-214) -148 + j*(69) -95 + j*(98) -322 + j*(-187) --102 + j*(-109) --287 + j*(66) --108 + j*(-247) -62 + j*(112) -86 + j*(-119) -75 + j*(65) --5 + j*(192) --112 + j*(0) -301 + j*(-56) --206 + j*(83) --30 + j*(192) --293 + j*(-1) -167 + j*(98) -144 + j*(-275) -76 + j*(80) --81 + j*(314) --132 + j*(-187) --124 + j*(-295) --412 + j*(339) -49 + j*(-5) --10 + j*(-172) --36 + j*(-47) --112 + j*(-105) -171 + j*(441) --104 + j*(-93) -128 + j*(211) --76 + j*(-84) -84 + j*(350) -47 + j*(-100) --137 + j*(-182) --22 + j*(-212) -8 + j*(100) --58 + j*(252) -55 + j*(40) --95 + j*(127) -252 + j*(-148) --147 + j*(-35) -202 + j*(-465) -127 + j*(-109) --136 + j*(-75) -122 + j*(67) -34 + j*(-97) --622 + j*(-2) -240 + j*(49) -230 + j*(95) --16 + j*(33) -129 + j*(178) --92 + j*(131) --146 + j*(-288) --11 + j*(-154) -243 + j*(-119) --293 + j*(-419) -12 + j*(146) -11 + j*(258) --267 + j*(-30) -378 + j*(180) --145 + j*(-53) --152 + j*(-247) --127 + j*(-30) -244 + j*(-144) --57 + j*(107) -324 + j*(203) -158 + j*(-66) -308 + j*(-268) -119 + j*(-105) --98 + j*(127) --189 + j*(-178) --35 + j*(-40) -142 + j*(378) --226 + j*(-28) -273 + j*(-14) -65 + j*(-8) --95 + j*(-134) --35 + j*(83) -49 + j*(157) --52 + j*(-219) -14 + j*(280) --33 + j*(-86) -86 + j*(-61) --508 + j*(-100) -161 + j*(-415) --86 + j*(-105) -65 + j*(-98) -233 + j*(69) --90 + j*(115) -47 + j*(171) --141 + j*(-136) -70 + j*(-102) --40 + j*(-204) --239 + j*(-93) -192 + j*(155) --231 + j*(32) --45 + j*(-419) -20 + j*(-41) -7 + j*(42) -258 + j*(-222) -98 + j*(-2) --13 + j*(62) --309 + j*(-131) -158 + j*(96) --309 + j*(-138) --322 + j*(-272) -168 + j*(-258) --395 + j*(131) -187 + j*(-576) --81 + j*(-438) --147 + j*(-62) --220 + j*(-71) --203 + j*(-38) -184 + j*(113) -0 + j*(-317) -167 + j*(-6) --226 + j*(78) --146 + j*(-158) --223 + j*(21) --170 + j*(70) -21 + j*(-109) --54 + j*(103) -407 + j*(-218) --4 + j*(-20) -207 + j*(-315) --80 + j*(-86) -180 + j*(-165) --144 + j*(289) -146 + j*(262) -38 + j*(-47) -352 + j*(281) -290 + j*(-41) --28 + j*(-112) -38 + j*(323) --56 + j*(-105) --68 + j*(74) -249 + j*(117) -13 + j*(223) --66 + j*(356) --146 + j*(-142) --55 + j*(216) -181 + j*(215) -252 + j*(74) -143 + j*(-118) -93 + j*(125) -29 + j*(22) --83 + j*(-94) -66 + j*(21) --62 + j*(146) -264 + j*(-65) --211 + j*(389) --119 + j*(245) -24 + j*(-66) -71 + j*(22) --1 + j*(-225) -80 + j*(-397) --206 + j*(-12) --6 + j*(158) -87 + j*(251) --8 + j*(139) --56 + j*(126) --327 + j*(45) -37 + j*(-74) --45 + j*(381) -94 + j*(-11) --6 + j*(46) --115 + j*(-161) -171 + j*(-400) --3 + j*(44) --228 + j*(208) --20 + j*(-47) --117 + j*(-197) --104 + j*(89) -102 + j*(-254) -76 + j*(-246) --368 + j*(-77) -49 + j*(107) -47 + j*(53) -87 + j*(-298) -199 + j*(-163) -116 + j*(-85) -25 + j*(-167) --1 + j*(74) --2 + j*(-13) -54 + j*(-91) -76 + j*(-262) -72 + j*(-146) --135 + j*(-182) -6 + j*(-18) --217 + j*(178) --46 + j*(69) --9 + j*(-42) --65 + j*(-80) --28 + j*(-10) --97 + j*(-62) -158 + j*(-168) -106 + j*(2) --184 + j*(-18) --233 + j*(16) -158 + j*(294) --172 + j*(-383) --199 + j*(-178) -125 + j*(-46) --41 + j*(17) --365 + j*(247) -262 + j*(-253) --105 + j*(72) --32 + j*(141) --2 + j*(-19) -143 + j*(-65) -42 + j*(125) -37 + j*(-173) -123 + j*(47) -45 + j*(-98) --40 + j*(143) -28 + j*(-257) -97 + j*(-254) -170 + j*(-148) --200 + j*(-47) --126 + j*(158) --278 + j*(21) -124 + j*(130) --147 + j*(-42) -8 + j*(200) --85 + j*(-76) -237 + j*(37) --167 + j*(184) -175 + j*(235) --180 + j*(380) --506 + j*(-137) --172 + j*(148) --28 + j*(23) -18 + j*(-223) --82 + j*(166) -11 + j*(121) -83 + j*(216) --210 + j*(-182) --269 + j*(99) -333 + j*(-19) --129 + j*(-68) -281 + j*(-123) --8 + j*(-74) --146 + j*(36) -91 + j*(-126) --94 + j*(45) --42 + j*(-46) -62 + j*(464) -89 + j*(-21) --281 + j*(67) -101 + j*(-325) -40 + j*(270) --163 + j*(107) --337 + j*(-230) --49 + j*(-117) -94 + j*(200) --100 + j*(119) --252 + j*(49) -164 + j*(40) -337 + j*(72) --47 + j*(-204) --224 + j*(-218) --180 + j*(218) -1 + j*(221) -221 + j*(-285) -259 + j*(-113) --71 + j*(366) --113 + j*(-133) -59 + j*(-132) -82 + j*(-6) --69 + j*(21) --182 + j*(-43) --27 + j*(-281) -80 + j*(-69) --54 + j*(-49) -91 + j*(-78) -214 + j*(-64) --216 + j*(246) --180 + j*(11) -81 + j*(-48) --34 + j*(-7) --8 + j*(57) --26 + j*(45) --324 + j*(264) -185 + j*(-170) --119 + j*(-197) -28 + j*(132) -16 + j*(67) -403 + j*(142) -152 + j*(152) --22 + j*(388) -44 + j*(0) -42 + j*(11) -35 + j*(-54) -182 + j*(-73) -153 + j*(-13) -159 + j*(-34) -316 + j*(83) -289 + j*(194) --134 + j*(-163) -87 + j*(117) -95 + j*(-318) -108 + j*(-79) --322 + j*(431) --1 + j*(314) -69 + j*(-359) -117 + j*(-21) --343 + j*(198) --25 + j*(-99) --10 + j*(-103) --76 + j*(182) --164 + j*(-390) --95 + j*(40) --181 + j*(182) --129 + j*(-161) --130 + j*(111) --20 + j*(1) --223 + j*(49) --129 + j*(119) --90 + j*(-31) -163 + j*(-215) --130 + j*(-217) -111 + j*(30) -40 + j*(63) --132 + j*(1) --240 + j*(-94) -301 + j*(-80) --62 + j*(-7) -85 + j*(-55) -144 + j*(4) --60 + j*(11) --43 + j*(-144) --178 + j*(136) -125 + j*(133) --44 + j*(124) -41 + j*(190) -75 + j*(223) --161 + j*(-218) -131 + j*(7) -21 + j*(102) --467 + j*(-260) -250 + j*(-82) -99 + j*(83) --223 + j*(349) --216 + j*(-151) -129 + j*(-349) -243 + j*(-324) -178 + j*(52) -194 + j*(-74) -146 + j*(200) -136 + j*(43) --378 + j*(-235) --290 + j*(151) -407 + j*(159) --139 + j*(-40) -130 + j*(-59) -135 + j*(353) -89 + j*(100) --30 + j*(-180) --50 + j*(-217) -76 + j*(-12) --197 + j*(-5) --296 + j*(0) --256 + j*(119) -233 + j*(-107) -16 + j*(-327) --274 + j*(325) -91 + j*(24) -47 + j*(-30) -211 + j*(-159) -277 + j*(18) -138 + j*(3) --142 + j*(-59) -212 + j*(-37) -97 + j*(382) -381 + j*(126) -221 + j*(-418) -328 + j*(-99) --93 + j*(-224) --30 + j*(-151) --246 + j*(-29) -230 + j*(13) -97 + j*(242) -8 + j*(-52) --58 + j*(141) -33 + j*(-67) --415 + j*(-201) --23 + j*(-113) --18 + j*(-187) -245 + j*(-151) -69 + j*(-96) --143 + j*(117) -179 + j*(47) -87 + j*(-223) --263 + j*(-198) --29 + j*(-86) -287 + j*(158) --59 + j*(113) -184 + j*(95) -264 + j*(42) --146 + j*(232) --67 + j*(-57) -19 + j*(-152) -187 + j*(182) --253 + j*(-218) -134 + j*(207) -91 + j*(-161) -131 + j*(-104) -132 + j*(-75) -95 + j*(427) --11 + j*(-45) --13 + j*(-20) --47 + j*(227) -86 + j*(66) -94 + j*(-35) --11 + j*(-71) --160 + j*(56) -36 + j*(255) -276 + j*(-119) -49 + j*(108) --98 + j*(-81) --76 + j*(-313) -240 + j*(4) --160 + j*(21) -8 + j*(-165) --163 + j*(261) --270 + j*(-73) -187 + j*(110) --86 + j*(-165) -214 + j*(134) --33 + j*(-112) --421 + j*(278) -19 + j*(46) -53 + j*(228) --442 + j*(-151) -69 + j*(59) --86 + j*(55) -50 + j*(-371) --199 + j*(113) --13 + j*(172) -168 + j*(52) -384 + j*(291) --89 + j*(-129) --343 + j*(-387) --37 + j*(300) --37 + j*(-66) --209 + j*(-116) -112 + j*(2) -87 + j*(-80) --272 + j*(-38) --51 + j*(40) --221 + j*(-138) --182 + j*(-378) --461 + j*(-30) --141 + j*(-149) -269 + j*(-55) -122 + j*(68) -122 + j*(33) --153 + j*(-116) --47 + j*(-1) -285 + j*(30) -102 + j*(-137) -50 + j*(-193) --409 + j*(-35) --162 + j*(171) -354 + j*(41) --216 + j*(101) -33 + j*(256) --114 + j*(203) --353 + j*(-30) -42 + j*(-177) --2 + j*(95) --100 + j*(-156) --117 + j*(-155) --144 + j*(-4) --138 + j*(-194) -33 + j*(-209) --113 + j*(6) --361 + j*(190) -153 + j*(-317) --49 + j*(81) --70 + j*(-52) -104 + j*(-284) -131 + j*(113) -28 + j*(6) -18 + j*(71) -47 + j*(100) -126 + j*(-6) --138 + j*(199) -18 + j*(-209) -158 + j*(-37) -237 + j*(-211) -277 + j*(-17) -87 + j*(151) --173 + j*(-153) -147 + j*(-314) --79 + j*(247) -128 + j*(-87) -26 + j*(-173) -236 + j*(-258) --177 + j*(25) --112 + j*(-148) --136 + j*(-163) --16 + j*(-223) --124 + j*(218) --49 + j*(-257) --156 + j*(-51) --25 + j*(-276) -88 + j*(1) --191 + j*(-42) --81 + j*(-92) -138 + j*(419) -2 + j*(88) --1 + j*(84) -119 + j*(194) --129 + j*(-187) --151 + j*(-66) --141 + j*(11) -107 + j*(-457) -256 + j*(140) -1 + j*(218) -130 + j*(134) -122 + j*(62) -96 + j*(-102) -72 + j*(-88) -59 + j*(-168) --111 + j*(-354) -189 + j*(-89) -224 + j*(-129) --127 + j*(88) -1 + j*(357) -139 + j*(163) -147 + j*(244) -100 + j*(94) -269 + j*(6) -13 + j*(-315) -71 + j*(-104) --110 + j*(30) -18 + j*(-172) --40 + j*(-19) --182 + j*(307) -129 + j*(344) --29 + j*(-144) --138 + j*(-13) -361 + j*(-96) --143 + j*(105) --92 + j*(-118) -16 + j*(52) --119 + j*(187) -296 + j*(-150) --188 + j*(-91) --7 + j*(-250) -83 + j*(-74) --110 + j*(113) --170 + j*(331) --52 + j*(-16) -97 + j*(-301) --269 + j*(-31) --89 + j*(69) -84 + j*(-25) -161 + j*(-239) --80 + j*(156) -148 + j*(-129) -191 + j*(196) --153 + j*(43) --117 + j*(-74) --46 + j*(-340) --41 + j*(-180) -53 + j*(-113) -182 + j*(195) -208 + j*(221) -6 + j*(14) -144 + j*(73) --83 + j*(-97) -30 + j*(223) --98 + j*(-148) --493 + j*(-247) --386 + j*(32) --112 + j*(326) -41 + j*(-60) -155 + j*(-324) -42 + j*(-76) --39 + j*(-154) -123 + j*(409) --132 + j*(-122) -209 + j*(-33) --313 + j*(55) -235 + j*(189) --382 + j*(339) -87 + j*(-11) -101 + j*(1) -186 + j*(-173) -23 + j*(-135) -427 + j*(74) -280 + j*(-122) --69 + j*(-35) -247 + j*(-23) -112 + j*(-204) -110 + j*(-6) --303 + j*(14) -245 + j*(250) --73 + j*(-16) -35 + j*(123) -49 + j*(49) --154 + j*(-42) --281 + j*(-35) --308 + j*(151) -151 + j*(22) -45 + j*(-136) --244 + j*(-184) --175 + j*(-62) -38 + j*(231) -6 + j*(98) --51 + j*(-29) --168 + j*(-286) -60 + j*(-317) -53 + j*(221) --120 + j*(98) --54 + j*(-115) -93 + j*(-67) -139 + j*(57) --66 + j*(108) --183 + j*(54) --59 + j*(-28) --165 + j*(35) --184 + j*(29) --275 + j*(165) -377 + j*(17) --283 + j*(-351) -42 + j*(141) -90 + j*(-40) --74 + j*(-148) -53 + j*(353) -4 + j*(-133) -440 + j*(-84) --33 + j*(113) -83 + j*(76) --175 + j*(-44) -69 + j*(-90) -103 + j*(135) -156 + j*(92) --122 + j*(-37) -48 + j*(-104) -250 + j*(-129) -88 + j*(190) --170 + j*(335) --293 + j*(20) -40 + j*(-365) -140 + j*(-265) -340 + j*(49) --47 + j*(135) -330 + j*(-47) --25 + j*(-161) --59 + j*(112) -185 + j*(186) -125 + j*(-295) --45 + j*(554) -100 + j*(13) -52 + j*(40) --13 + j*(-54) --218 + j*(-153) -11 + j*(-43) --39 + j*(3) -10 + j*(-15) --298 + j*(9) -123 + j*(-210) -179 + j*(-168) -211 + j*(-169) -250 + j*(216) -74 + j*(-95) --288 + j*(59) --35 + j*(135) -23 + j*(127) --22 + j*(190) --76 + j*(-112) -180 + j*(-251) -226 + j*(-145) -30 + j*(37) -79 + j*(137) -83 + j*(-292) -209 + j*(-6) --307 + j*(-122) -119 + j*(-90) -26 + j*(-105) --28 + j*(-279) --95 + j*(-34) --57 + j*(-282) --361 + j*(-175) --83 + j*(-77) --74 + j*(16) -370 + j*(52) --276 + j*(-269) -285 + j*(-62) --129 + j*(-197) --21 + j*(-14) --3 + j*(45) -371 + j*(43) --213 + j*(-98) -196 + j*(23) -187 + j*(62) --165 + j*(173) -61 + j*(-60) -194 + j*(-329) --269 + j*(-18) -160 + j*(-72) -62 + j*(284) -47 + j*(-228) --74 + j*(294) -64 + j*(78) -37 + j*(-100) --81 + j*(50) -18 + j*(-113) -157 + j*(217) -188 + j*(355) -37 + j*(-31) -176 + j*(-282) -190 + j*(28) -81 + j*(-1) --202 + j*(311) --52 + j*(120) --18 + j*(17) --330 + j*(-110) --84 + j*(472) -51 + j*(234) --144 + j*(366) --25 + j*(12) --69 + j*(-14) -540 + j*(-155) -52 + j*(81) -174 + j*(-171) -117 + j*(-86) --15 + j*(-315) -154 + j*(135) -107 + j*(97) --119 + j*(-209) -67 + j*(-233) -14 + j*(58) --94 + j*(159) --81 + j*(1) -107 + j*(-90) --29 + j*(38) --565 + j*(-190) --35 + j*(36) -255 + j*(220) --25 + j*(18) --337 + j*(-27) -89 + j*(-148) --89 + j*(-141) --12 + j*(20) -69 + j*(-27) -228 + j*(-64) -112 + j*(-27) --181 + j*(81) --102 + j*(-2) -61 + j*(257) --170 + j*(8) --4 + j*(-171) --119 + j*(-27) --156 + j*(10) -315 + j*(-231) -264 + j*(260) --37 + j*(129) -69 + j*(-72) -121 + j*(146) --37 + j*(221) --195 + j*(1) -301 + j*(107) -221 + j*(16) --313 + j*(-181) --51 + j*(-94) -140 + j*(-295) -6 + j*(-176) --135 + j*(4) --49 + j*(355) -87 + j*(69) --40 + j*(-108) -81 + j*(187) -51 + j*(-194) --98 + j*(175) --280 + j*(127) -194 + j*(-100) --287 + j*(185) --28 + j*(14) -57 + j*(55) --313 + j*(-42) -175 + j*(-13) --138 + j*(136) --7 + j*(27) -16 + j*(214) --4 + j*(70) --28 + j*(-166) --91 + j*(214) --64 + j*(-305) -293 + j*(-61) -268 + j*(182) -153 + j*(23) --50 + j*(-63) -57 + j*(-17) --127 + j*(47) --107 + j*(-67) -68 + j*(83) -38 + j*(-78) --169 + j*(-76) -132 + j*(134) -202 + j*(197) --224 + j*(140) --37 + j*(643) --233 + j*(16) --227 + j*(-88) --168 + j*(-213) -63 + j*(-224) -88 + j*(28) -8 + j*(165) --273 + j*(-146) --140 + j*(-8) --100 + j*(13) --232 + j*(1) --223 + j*(93) --132 + j*(-45) --20 + j*(248) -156 + j*(-44) -74 + j*(-89) -88 + j*(26) -161 + j*(-94) --11 + j*(-143) --145 + j*(124) --33 + j*(30) -485 + j*(173) -249 + j*(-310) --246 + j*(164) --104 + j*(134) --126 + j*(184) --135 + j*(259) -18 + j*(79) --115 + j*(67) --190 + j*(-126) --159 + j*(183) -184 + j*(-190) -390 + j*(-129) --35 + j*(-129) -342 + j*(363) -110 + j*(-233) -158 + j*(-269) -15 + j*(-55) --204 + j*(-508) -11 + j*(165) --346 + j*(-145) --168 + j*(75) --175 + j*(-120) --25 + j*(294) --119 + j*(337) --119 + j*(111) -11 + j*(-257) --141 + j*(-127) -116 + j*(57) --173 + j*(30) --138 + j*(68) --71 + j*(-35) -14 + j*(250) --11 + j*(-57) -57 + j*(-279) -74 + j*(274) --81 + j*(64) --378 + j*(-80) --279 + j*(211) --79 + j*(194) --6 + j*(261) -156 + j*(-58) --8 + j*(-139) -239 + j*(-23) --117 + j*(-64) --107 + j*(41) --198 + j*(-283) --91 + j*(-135) --43 + j*(-13) -99 + j*(30) -4 + j*(105) --276 + j*(319) --298 + j*(-84) --7 + j*(-237) --286 + j*(9) -74 + j*(122) -10 + j*(344) --185 + j*(161) -139 + j*(187) --332 + j*(-48) --35 + j*(-204) --7 + j*(-144) --6 + j*(266) -78 + j*(25) -37 + j*(78) -96 + j*(183) --107 + j*(-141) -66 + j*(-433) --127 + j*(-27) --96 + j*(138) --1 + j*(-129) --351 + j*(71) --324 + j*(202) --93 + j*(-97) -73 + j*(153) -115 + j*(-252) -156 + j*(172) --312 + j*(-143) --336 + j*(-115) --119 + j*(-85) -47 + j*(-141) -300 + j*(174) --219 + j*(57) -102 + j*(-172) -45 + j*(390) -17 + j*(-127) -31 + j*(135) -344 + j*(83) --76 + j*(140) -53 + j*(57) -199 + j*(192) --69 + j*(165) -5 + j*(216) -525 + j*(152) --233 + j*(-83) --221 + j*(283) -50 + j*(12) -214 + j*(-559) --118 + j*(-131) --77 + j*(-31) --30 + j*(-192) -130 + j*(-141) -215 + j*(296) --64 + j*(65) -209 + j*(-41) -81 + j*(219) --110 + j*(-412) -119 + j*(130) -199 + j*(-42) -72 + j*(-13) --223 + j*(53) -45 + j*(28) -262 + j*(-16) -11 + j*(78) -182 + j*(-139) -73 + j*(211) -183 + j*(11) --7 + j*(171) -65 + j*(-11) --12 + j*(-45) -10 + j*(251) -110 + j*(-240) -187 + j*(-95) --42 + j*(-128) -26 + j*(117) --77 + j*(128) --45 + j*(70) -74 + j*(-117) --28 + j*(109) --175 + j*(-98) -119 + j*(204) -8 + j*(298) --43 + j*(-71) -105 + j*(107) --46 + j*(31) --23 + j*(-230) --141 + j*(-225) --245 + j*(-98) --115 + j*(-24) -52 + j*(330) --5 + j*(218) --179 + j*(37) -50 + j*(52) -40 + j*(127) --165 + j*(-45) -199 + j*(-132) -242 + j*(-7) --489 + j*(-55) --220 + j*(-413) -80 + j*(-27) --104 + j*(103) --245 + j*(383) --40 + j*(-466) -197 + j*(144) --98 + j*(13) --8 + j*(345) -335 + j*(190) -42 + j*(35) -157 + j*(58) -175 + j*(-229) -284 + j*(-218) -421 + j*(283) -272 + j*(-241) --252 + j*(157) --209 + j*(22) --40 + j*(-61) --30 + j*(84) -293 + j*(-244) --286 + j*(241) --197 + j*(-78) --107 + j*(-2) --329 + j*(-105) -93 + j*(-472) -187 + j*(-107) --279 + j*(150) --337 + j*(211) -117 + j*(-244) --221 + j*(267) -224 + j*(70) -174 + j*(168) --124 + j*(-14) -16 + j*(-190) --207 + j*(305) -143 + j*(54) --124 + j*(30) -43 + j*(-15) --67 + j*(-205) -21 + j*(-163) -157 + j*(-183) --59 + j*(-42) --53 + j*(-147) -231 + j*(30) --61 + j*(-77) -4 + j*(-422) --378 + j*(259) -74 + j*(-154) -36 + j*(153) --182 + j*(-66) -189 + j*(-37) --129 + j*(-29) -46 + j*(-117) --88 + j*(-76) --23 + j*(164) --111 + j*(-12) --228 + j*(-86) -134 + j*(-25) --142 + j*(93) --182 + j*(25) -215 + j*(-70) -181 + j*(-52) -212 + j*(156) -421 + j*(-248) -52 + j*(-489) -36 + j*(86) -105 + j*(-277) -283 + j*(-57) -250 + j*(73) -86 + j*(-120) --230 + j*(-105) --86 + j*(-75) --118 + j*(88) -59 + j*(-71) --106 + j*(-66) --314 + j*(-8) --16 + j*(270) --138 + j*(189) --151 + j*(-110) -365 + j*(-158) --216 + j*(-23) -4 + j*(181) --245 + j*(88) --132 + j*(202) --115 + j*(-160) -69 + j*(310) -47 + j*(45) -104 + j*(72) -260 + j*(204) --190 + j*(46) --192 + j*(312) -8 + j*(-155) --162 + j*(90) --115 + j*(44) --37 + j*(-298) --72 + j*(238) -170 + j*(310) -72 + j*(248) --28 + j*(151) -103 + j*(-130) -78 + j*(-173) -120 + j*(-121) -435 + j*(-305) --20 + j*(45) --93 + j*(235) -66 + j*(-35) -204 + j*(4) --134 + j*(50) --397 + j*(-16) -91 + j*(166) -112 + j*(-139) --42 + j*(-366) -25 + j*(223) -79 + j*(-212) --67 + j*(-242) --235 + j*(-83) --160 + j*(62) -124 + j*(347) -110 + j*(-49) -127 + j*(49) -167 + j*(-341) --427 + j*(-66) --172 + j*(82) --130 + j*(-25) --9 + j*(-11) -99 + j*(252) --225 + j*(-153) --220 + j*(175) -141 + j*(122) -110 + j*(288) --286 + j*(149) --47 + j*(218) -322 + j*(127) -159 + j*(101) --252 + j*(185) --443 + j*(-124) -10 + j*(165) -182 + j*(169) --32 + j*(-81) --44 + j*(-41) --229 + j*(50) -157 + j*(421) --155 + j*(-18) --85 + j*(-13) -148 + j*(-432) --298 + j*(-108) --260 + j*(219) -272 + j*(-179) -35 + j*(-123) -137 + j*(8) -29 + j*(-116) -84 + j*(167) -308 + j*(-47) -204 + j*(64) -339 + j*(-60) --224 + j*(-70) -186 + j*(730) --59 + j*(86) -66 + j*(-30) --16 + j*(-260) --309 + j*(200) --143 + j*(-127) -33 + j*(-50) -12 + j*(-74) --113 + j*(-52) --31 + j*(197) -330 + j*(197) -264 + j*(-106) -214 + j*(-164) --8 + j*(431) --143 + j*(66) -98 + j*(66) --65 + j*(92) -233 + j*(145) --93 + j*(133) -28 + j*(-104) --283 + j*(89) -91 + j*(-319) -53 + j*(111) -57 + j*(139) -90 + j*(88) -45 + j*(66) --43 + j*(140) -307 + j*(127) -173 + j*(-86) -115 + j*(-327) -255 + j*(-238) -212 + j*(-170) -173 + j*(279) -49 + j*(142) -6 + j*(3) -218 + j*(184) --39 + j*(-110) --10 + j*(-238) -30 + j*(303) -35 + j*(-55) -6 + j*(-54) -140 + j*(-167) -62 + j*(52) -204 + j*(-169) --64 + j*(163) --135 + j*(70) -82 + j*(63) -21 + j*(80) --81 + j*(-139) --84 + j*(76) --129 + j*(-13) --10 + j*(-159) -27 + j*(192) --158 + j*(118) -81 + j*(-167) -64 + j*(-67) --82 + j*(48) --18 + j*(102) --343 + j*(83) -161 + j*(-159) --10 + j*(460) --13 + j*(-252) -148 + j*(-252) --69 + j*(61) --152 + j*(48) -38 + j*(137) -90 + j*(40) -39 + j*(-65) -85 + j*(244) --76 + j*(-138) --209 + j*(59) --16 + j*(-194) -424 + j*(175) --57 + j*(-143) -21 + j*(239) -93 + j*(93) -75 + j*(151) --66 + j*(-127) -124 + j*(57) -78 + j*(142) --124 + j*(107) --184 + j*(-105) --43 + j*(83) -86 + j*(50) --46 + j*(1) -108 + j*(-211) -47 + j*(-100) --136 + j*(-327) -45 + j*(124) -471 + j*(-310) --72 + j*(52) --329 + j*(-104) -34 + j*(260) -433 + j*(-45) --202 + j*(-414) --115 + j*(-4) --67 + j*(143) --21 + j*(462) -74 + j*(-28) --301 + j*(-155) -107 + j*(-202) --85 + j*(26) --31 + j*(322) -416 + j*(352) --236 + j*(-16) -15 + j*(235) --250 + j*(120) --171 + j*(-234) -380 + j*(-51) -301 + j*(91) -118 + j*(79) -20 + j*(-35) -106 + j*(175) --217 + j*(-156) -146 + j*(156) --88 + j*(237) -573 + j*(-96) -68 + j*(90) -31 + j*(-156) --256 + j*(41) -119 + j*(249) -40 + j*(115) -82 + j*(131) -71 + j*(67) --373 + j*(37) -78 + j*(-76) --20 + j*(71) --38 + j*(-23) -117 + j*(-29) --78 + j*(-358) --199 + j*(-98) -228 + j*(165) -51 + j*(-88) --136 + j*(300) -76 + j*(46) --58 + j*(-200) -82 + j*(-96) --204 + j*(-250) -209 + j*(462) --178 + j*(20) --187 + j*(236) -296 + j*(-223) --211 + j*(-119) --232 + j*(199) --223 + j*(-18) -101 + j*(165) --349 + j*(-64) --121 + j*(-27) --192 + j*(513) -35 + j*(-97) -139 + j*(103) -209 + j*(-49) -97 + j*(73) -105 + j*(3) -54 + j*(-61) --60 + j*(257) -112 + j*(57) -193 + j*(-144) -88 + j*(24) -150 + j*(-133) -42 + j*(90) -409 + j*(-157) --37 + j*(-123) -156 + j*(136) --146 + j*(61) -153 + j*(-356) --45 + j*(-37) --69 + j*(198) --408 + j*(202) --18 + j*(102) -259 + j*(-2) -220 + j*(-238) --82 + j*(-42) -68 + j*(65) --25 + j*(144) -303 + j*(-100) -6 + j*(81) --25 + j*(47) -106 + j*(245) --204 + j*(-276) -59 + j*(23) --472 + j*(161) --196 + j*(-26) -266 + j*(-304) -132 + j*(-221) --108 + j*(28) --82 + j*(-34) --107 + j*(-3) --110 + j*(91) --11 + j*(-317) -106 + j*(76) -28 + j*(-119) -32 + j*(-52) --256 + j*(33) --46 + j*(-450) --10 + j*(-294) -454 + j*(-266) -89 + j*(-168) -100 + j*(-173) -240 + j*(71) -69 + j*(-199) --110 + j*(71) --36 + j*(18) --145 + j*(103) --317 + j*(-51) -11 + j*(62) -184 + j*(78) -182 + j*(-217) --168 + j*(-93) --58 + j*(75) --173 + j*(-167) --139 + j*(153) -47 + j*(-235) -128 + j*(-67) --226 + j*(143) --220 + j*(-101) -240 + j*(-123) --86 + j*(-377) -52 + j*(30) --39 + j*(-147) -236 + j*(-35) -150 + j*(-226) --52 + j*(-192) --37 + j*(187) --201 + j*(52) --146 + j*(116) --168 + j*(123) -54 + j*(-331) --33 + j*(-58) --139 + j*(-2) -23 + j*(-123) -94 + j*(-83) -127 + j*(158) --29 + j*(-93) -148 + j*(269) --21 + j*(227) --178 + j*(-3) --72 + j*(-140) -35 + j*(13) --14 + j*(122) --113 + j*(63) --177 + j*(6) --291 + j*(250) --184 + j*(260) --119 + j*(-229) --255 + j*(-19) --83 + j*(-202) -14 + j*(-102) --83 + j*(91) -100 + j*(-115) --289 + j*(83) --209 + j*(-58) --3 + j*(-247) -164 + j*(-134) -380 + j*(18) -40 + j*(-62) --132 + j*(-80) --1 + j*(-203) --175 + j*(-139) -50 + j*(92) --28 + j*(-29) -181 + j*(40) --241 + j*(40) -221 + j*(166) -81 + j*(-112) -4 + j*(-86) --7 + j*(-132) --78 + j*(-117) --152 + j*(92) --62 + j*(-200) --28 + j*(72) -186 + j*(-240) --9 + j*(148) -81 + j*(-139) --62 + j*(-86) --14 + j*(-98) -125 + j*(-161) --198 + j*(306) --57 + j*(33) -122 + j*(-140) --69 + j*(-103) --66 + j*(308) --9 + j*(206) --63 + j*(33) -175 + j*(15) --42 + j*(-182) -6 + j*(45) --218 + j*(15) --93 + j*(-39) -30 + j*(81) -66 + j*(405) --52 + j*(373) -467 + j*(55) -17 + j*(81) -145 + j*(226) --86 + j*(-193) --112 + j*(-109) -203 + j*(-74) --12 + j*(-225) -52 + j*(-145) --61 + j*(330) -98 + j*(-218) -114 + j*(-56) -31 + j*(-127) --337 + j*(-109) -212 + j*(-71) --111 + j*(-33) -113 + j*(250) -195 + j*(-205) --23 + j*(88) -151 + j*(-217) -105 + j*(-339) -139 + j*(275) --42 + j*(407) -215 + j*(-210) --390 + j*(-214) --330 + j*(-141) --125 + j*(-173) -164 + j*(-199) -262 + j*(43) -172 + j*(355) -69 + j*(151) --35 + j*(-54) --218 + j*(-117) -13 + j*(276) --42 + j*(-181) -176 + j*(-191) --174 + j*(-44) --300 + j*(-130) -29 + j*(-37) --274 + j*(-3) --23 + j*(57) -122 + j*(-143) -215 + j*(17) -78 + j*(110) --305 + j*(83) --4 + j*(43) -92 + j*(-425) --323 + j*(-36) --18 + j*(-63) -63 + j*(8) -50 + j*(170) -105 + j*(79) --18 + j*(-273) --66 + j*(-273) -86 + j*(-55) -173 + j*(-37) --87 + j*(30) -107 + j*(-247) -57 + j*(134) --118 + j*(518) -164 + j*(-260) -155 + j*(-93) -95 + j*(42) -293 + j*(-62) --26 + j*(250) -129 + j*(216) -86 + j*(69) -191 + j*(1) -214 + j*(-134) --308 + j*(-433) --33 + j*(-70) --98 + j*(57) -116 + j*(19) --248 + j*(185) -74 + j*(-148) --2 + j*(-165) -32 + j*(238) --4 + j*(170) --112 + j*(-122) -343 + j*(62) -145 + j*(72) --62 + j*(383) --105 + j*(-106) --480 + j*(200) -184 + j*(346) -83 + j*(-158) -187 + j*(170) --105 + j*(-212) --326 + j*(140) -240 + j*(-288) -107 + j*(-84) --231 + j*(-215) --162 + j*(99) --205 + j*(202) --89 + j*(170) -128 + j*(-134) -31 + j*(-245) --21 + j*(45) --5 + j*(32) --71 + j*(138) --300 + j*(55) -31 + j*(-25) --2 + j*(153) -163 + j*(-122) --132 + j*(-221) -192 + j*(62) --168 + j*(4) --10 + j*(-241) -193 + j*(-8) -31 + j*(-57) --58 + j*(-64) --134 + j*(-218) -78 + j*(-81) --13 + j*(107) --163 + j*(-23) --287 + j*(189) --226 + j*(-65) -54 + j*(-36) -25 + j*(260) -177 + j*(167) --83 + j*(245) --95 + j*(-302) -97 + j*(-70) -135 + j*(-128) -15 + j*(-54) -57 + j*(-5) -33 + j*(9) -196 + j*(297) --26 + j*(-111) --112 + j*(211) --215 + j*(54) --286 + j*(-7) -157 + j*(81) -626 + j*(96) -157 + j*(170) --2 + j*(116) --131 + j*(10) -443 + j*(48) --343 + j*(-14) --46 + j*(136) -235 + j*(98) -298 + j*(-99) -27 + j*(-122) --303 + j*(269) --65 + j*(-224) -86 + j*(119) -363 + j*(-146) -289 + j*(112) -416 + j*(-343) -23 + j*(62) -359 + j*(-118) -43 + j*(-156) -3 + j*(-25) --28 + j*(112) -100 + j*(211) --28 + j*(47) --169 + j*(18) -107 + j*(-104) --50 + j*(-117) -269 + j*(-52) -13 + j*(-81) --108 + j*(12) --103 + j*(-257) --258 + j*(93) --202 + j*(211) --117 + j*(-83) -5 + j*(-173) --289 + j*(281) --30 + j*(175) --20 + j*(-96) -177 + j*(40) --42 + j*(-80) --156 + j*(-88) --87 + j*(56) -112 + j*(42) --115 + j*(-334) -121 + j*(123) --197 + j*(308) -43 + j*(-219) --191 + j*(-131) -19 + j*(-239) --103 + j*(-7) --67 + j*(-83) --372 + j*(-101) -211 + j*(-40) --242 + j*(-88) --66 + j*(-199) --8 + j*(30) -183 + j*(-58) -59 + j*(220) -288 + j*(62) -233 + j*(109) -23 + j*(127) --99 + j*(-173) --48 + j*(-95) -182 + j*(167) -146 + j*(-223) -209 + j*(-64) -23 + j*(243) -65 + j*(78) --36 + j*(30) --384 + j*(-61) -187 + j*(9) --46 + j*(-52) -187 + j*(-119) -26 + j*(199) --296 + j*(-226) -224 + j*(-408) --184 + j*(221) --184 + j*(174) -83 + j*(107) --125 + j*(-95) -417 + j*(197) -10 + j*(-238) -32 + j*(-39) --59 + j*(161) -74 + j*(272) -291 + j*(139) --144 + j*(81) --321 + j*(0) -125 + j*(-56) --44 + j*(32) -57 + j*(-141) --115 + j*(32) -91 + j*(103) --204 + j*(-151) --112 + j*(-84) --49 + j*(42) -67 + j*(-351) --51 + j*(61) --269 + j*(54) --247 + j*(-315) -38 + j*(-28) -17 + j*(-354) -157 + j*(-127) -267 + j*(85) -137 + j*(-86) --77 + j*(-158) -344 + j*(-275) --101 + j*(136) --156 + j*(-459) --9 + j*(-119) -344 + j*(33) -16 + j*(-237) -74 + j*(-71) --19 + j*(321) -228 + j*(-115) --228 + j*(82) --291 + j*(49) --216 + j*(-457) --161 + j*(-90) --145 + j*(85) --417 + j*(130) --32 + j*(51) --341 + j*(-24) -60 + j*(174) --70 + j*(220) --177 + j*(-25) --42 + j*(-177) -141 + j*(-44) -126 + j*(-156) -180 + j*(-93) -239 + j*(-163) --242 + j*(-108) -74 + j*(133) -24 + j*(-28) --310 + j*(242) -134 + j*(201) --296 + j*(119) --98 + j*(-12) -69 + j*(71) --313 + j*(-73) -28 + j*(-25) -62 + j*(-102) --325 + j*(136) -322 + j*(-87) -64 + j*(247) --152 + j*(86) -95 + j*(-110) -145 + j*(344) -95 + j*(-163) --30 + j*(-364) -276 + j*(-101) -104 + j*(-206) -119 + j*(-93) --153 + j*(324) --3 + j*(-38) -70 + j*(83) --1 + j*(-329) --12 + j*(122) -41 + j*(104) --51 + j*(-198) -129 + j*(61) -4 + j*(23) -214 + j*(-16) --95 + j*(90) --84 + j*(-9) --159 + j*(78) --108 + j*(278) -156 + j*(-250) -106 + j*(172) -184 + j*(155) -159 + j*(47) --63 + j*(87) --8 + j*(115) --214 + j*(-180) --78 + j*(-164) -63 + j*(-165) --56 + j*(290) --69 + j*(-195) --155 + j*(53) -139 + j*(180) -205 + j*(-108) -30 + j*(342) --103 + j*(37) --204 + j*(-105) --125 + j*(-243) -211 + j*(306) --264 + j*(-107) --119 + j*(-308) -34 + j*(163) -5 + j*(112) -279 + j*(43) -209 + j*(-43) -15 + j*(157) -262 + j*(-8) -26 + j*(194) -170 + j*(-77) --65 + j*(-503) -18 + j*(-21) -228 + j*(-116) --71 + j*(54) -98 + j*(-200) -273 + j*(0) --126 + j*(-49) -118 + j*(-24) --1 + j*(21) --122 + j*(74) -247 + j*(-27) --94 + j*(252) -31 + j*(-20) -153 + j*(44) -38 + j*(-140) -62 + j*(200) --21 + j*(-37) -126 + j*(191) --3 + j*(-28) -261 + j*(284) --329 + j*(-189) -23 + j*(-105) -200 + j*(-269) -113 + j*(36) -61 + j*(151) --50 + j*(49) --150 + j*(-70) --115 + j*(-88) --46 + j*(-153) -100 + j*(92) --61 + j*(138) --35 + j*(-166) --185 + j*(189) -254 + j*(-180) -47 + j*(464) -24 + j*(273) --240 + j*(-223) --3 + j*(-196) --204 + j*(189) --33 + j*(-244) --112 + j*(-252) --103 + j*(-173) --12 + j*(-321) --150 + j*(-90) --26 + j*(238) -209 + j*(-52) -217 + j*(262) --211 + j*(69) -165 + j*(177) -13 + j*(-94) --110 + j*(-168) -167 + j*(-127) --100 + j*(64) -98 + j*(164) -138 + j*(-101) -97 + j*(-344) --255 + j*(33) --40 + j*(-127) -99 + j*(-166) --106 + j*(-271) -240 + j*(18) --58 + j*(-147) --145 + j*(50) --203 + j*(-132) -12 + j*(-170) --270 + j*(175) --47 + j*(-71) -279 + j*(-226) -181 + j*(202) -24 + j*(13) -65 + j*(148) --98 + j*(240) -36 + j*(206) -134 + j*(12) --144 + j*(-184) --402 + j*(83) --103 + j*(119) --62 + j*(-148) --113 + j*(202) --266 + j*(41) -185 + j*(-2) --196 + j*(-76) --123 + j*(-203) --195 + j*(-21) --23 + j*(232) --156 + j*(225) -219 + j*(152) -155 + j*(-184) --100 + j*(-13) --29 + j*(-129) -357 + j*(-53) -192 + j*(-126) --6 + j*(-172) -57 + j*(114) -183 + j*(-358) -47 + j*(-211) --42 + j*(131) --194 + j*(-122) --171 + j*(304) -31 + j*(95) --160 + j*(281) -37 + j*(-166) --142 + j*(37) -6 + j*(342) --55 + j*(-177) --20 + j*(-42) --351 + j*(87) -225 + j*(-8) -92 + j*(258) -71 + j*(83) -103 + j*(-59) -182 + j*(42) -78 + j*(-264) --153 + j*(-325) --160 + j*(25) -21 + j*(91) --123 + j*(-245) -81 + j*(-151) -277 + j*(63) --86 + j*(-250) --173 + j*(30) -86 + j*(-86) -11 + j*(95) -61 + j*(-32) --122 + j*(25) --52 + j*(-103) --93 + j*(445) -105 + j*(16) --68 + j*(-42) -129 + j*(-107) --199 + j*(-258) --273 + j*(108) -93 + j*(4) -176 + j*(-44) -98 + j*(-21) --145 + j*(-4) --192 + j*(22) --33 + j*(96) --176 + j*(-115) --29 + j*(47) --221 + j*(98) -139 + j*(249) -260 + j*(-54) --64 + j*(-2) -252 + j*(-52) -150 + j*(-151) -6 + j*(145) --78 + j*(136) -315 + j*(91) -30 + j*(91) --70 + j*(2) -105 + j*(-147) --159 + j*(380) -475 + j*(-3) -221 + j*(130) -224 + j*(-352) -23 + j*(180) -57 + j*(19) --322 + j*(94) --28 + j*(-117) -156 + j*(-285) -68 + j*(109) --77 + j*(-47) -87 + j*(-23) -392 + j*(44) --187 + j*(-203) --108 + j*(-540) --227 + j*(45) -2 + j*(-269) --64 + j*(204) --185 + j*(-205) --119 + j*(2) -404 + j*(-132) --144 + j*(20) -160 + j*(181) --283 + j*(86) -33 + j*(-139) --195 + j*(69) -117 + j*(-152) --308 + j*(-221) -337 + j*(127) --18 + j*(-202) -118 + j*(-132) -13 + j*(-235) --29 + j*(-47) -206 + j*(41) --243 + j*(306) -5 + j*(137) --48 + j*(42) --547 + j*(-230) --20 + j*(53) --49 + j*(0) -20 + j*(211) --115 + j*(359) -22 + j*(158) --108 + j*(-13) -169 + j*(-289) -92 + j*(69) --124 + j*(95) -113 + j*(-54) --382 + j*(-159) -274 + j*(214) --21 + j*(224) -29 + j*(59) -496 + j*(233) --115 + j*(-141) -246 + j*(-170) --75 + j*(-33) -251 + j*(-71) -7 + j*(144) -119 + j*(-99) -197 + j*(16) -52 + j*(-139) -17 + j*(-294) --66 + j*(177) --299 + j*(-142) -139 + j*(142) -34 + j*(126) -16 + j*(260) -90 + j*(44) --303 + j*(196) -67 + j*(-71) -74 + j*(179) -211 + j*(-202) -349 + j*(378) -444 + j*(3) -31 + j*(98) --217 + j*(-99) -35 + j*(98) --111 + j*(211) -253 + j*(69) -312 + j*(-1) -139 + j*(163) --30 + j*(5) --177 + j*(112) --195 + j*(211) --254 + j*(-32) --90 + j*(8) -170 + j*(-214) -254 + j*(257) --179 + j*(6) --69 + j*(202) -98 + j*(128) --197 + j*(-299) --250 + j*(-177) -156 + j*(-23) --64 + j*(-156) --35 + j*(-64) -32 + j*(101) --92 + j*(-60) -180 + j*(22) -21 + j*(134) -166 + j*(-83) -423 + j*(7) -12 + j*(219) -37 + j*(168) -1 + j*(118) -42 + j*(-40) --148 + j*(-71) --93 + j*(-12) --103 + j*(-221) -298 + j*(49) -56 + j*(91) -340 + j*(52) --117 + j*(132) -10 + j*(24) --24 + j*(151) --82 + j*(-61) -126 + j*(-199) --42 + j*(249) -102 + j*(74) -53 + j*(126) -245 + j*(161) --50 + j*(285) -106 + j*(136) -235 + j*(-6) -120 + j*(-202) -165 + j*(-13) --181 + j*(81) -318 + j*(-256) --25 + j*(137) -153 + j*(128) -123 + j*(-73) -61 + j*(51) --190 + j*(268) --363 + j*(214) -11 + j*(42) -75 + j*(-95) --62 + j*(-16) --15 + j*(-403) --33 + j*(-66) -95 + j*(64) --129 + j*(-220) --33 + j*(33) --38 + j*(-90) -103 + j*(-49) -252 + j*(227) -25 + j*(-282) -98 + j*(64) -151 + j*(-88) --182 + j*(117) --89 + j*(-91) --313 + j*(-100) --117 + j*(-107) -8 + j*(-174) --83 + j*(-45) --324 + j*(83) -47 + j*(70) -97 + j*(81) -223 + j*(375) -43 + j*(13) --156 + j*(103) --112 + j*(117) --36 + j*(65) --18 + j*(174) --209 + j*(-86) -173 + j*(-186) -130 + j*(-262) -1 + j*(74) --180 + j*(31) --285 + j*(295) --158 + j*(-69) --165 + j*(86) --221 + j*(-175) --166 + j*(47) --202 + j*(162) -263 + j*(47) -187 + j*(-681) -63 + j*(-173) -74 + j*(119) -23 + j*(-364) --226 + j*(-106) --11 + j*(293) -32 + j*(243) -63 + j*(-235) --28 + j*(42) --165 + j*(228) -375 + j*(98) --142 + j*(115) -131 + j*(85) -41 + j*(-390) -202 + j*(339) --311 + j*(91) -194 + j*(-33) -49 + j*(479) -59 + j*(-524) -310 + j*(266) -131 + j*(-93) -77 + j*(6) --170 + j*(180) -45 + j*(165) --6 + j*(151) -291 + j*(-45) --74 + j*(163) -70 + j*(148) -209 + j*(-54) --52 + j*(296) -426 + j*(-81) -6 + j*(100) -305 + j*(14) -37 + j*(95) -11 + j*(294) --152 + j*(-21) --30 + j*(-151) -47 + j*(-141) -391 + j*(12) --60 + j*(-167) -16 + j*(110) -161 + j*(6) -213 + j*(158) -35 + j*(-8) -231 + j*(-83) -119 + j*(190) --35 + j*(191) -35 + j*(339) --9 + j*(35) -249 + j*(-193) --153 + j*(162) -175 + j*(-298) --35 + j*(150) --11 + j*(-353) -231 + j*(-64) --139 + j*(-264) --25 + j*(203) -105 + j*(-223) -94 + j*(125) -150 + j*(-11) -170 + j*(71) -69 + j*(13) -128 + j*(126) --145 + j*(44) --33 + j*(166) --4 + j*(153) --42 + j*(0) --281 + j*(40) --43 + j*(230) --202 + j*(-315) -210 + j*(-83) -193 + j*(-252) -221 + j*(-6) --262 + j*(81) --247 + j*(58) -66 + j*(122) -73 + j*(-110) --47 + j*(-16) --62 + j*(54) -153 + j*(-28) --28 + j*(-310) -55 + j*(-151) -92 + j*(27) --258 + j*(-75) -206 + j*(-6) -66 + j*(60) --139 + j*(-156) -50 + j*(134) --24 + j*(103) -165 + j*(155) -30 + j*(206) -67 + j*(74) -5 + j*(-52) --168 + j*(-119) -69 + j*(59) -54 + j*(-223) --196 + j*(1) -217 + j*(-269) -88 + j*(282) --47 + j*(33) --124 + j*(-10) --184 + j*(-282) --325 + j*(94) -40 + j*(331) --44 + j*(-128) -56 + j*(163) --107 + j*(-361) -278 + j*(120) -62 + j*(84) -206 + j*(219) --192 + j*(-233) -170 + j*(-263) -71 + j*(-114) -260 + j*(293) --4 + j*(91) --110 + j*(-105) --269 + j*(-175) --282 + j*(210) -213 + j*(-96) -312 + j*(33) --138 + j*(-117) -18 + j*(-124) -75 + j*(-114) --409 + j*(21) --54 + j*(98) -78 + j*(-160) -42 + j*(-13) --27 + j*(-368) --54 + j*(191) -87 + j*(95) --26 + j*(110) -15 + j*(-362) -325 + j*(-46) --42 + j*(-44) -108 + j*(-125) --49 + j*(117) --66 + j*(71) --21 + j*(-75) --243 + j*(-115) --77 + j*(46) -162 + j*(222) -165 + j*(131) -72 + j*(-66) --47 + j*(21) -112 + j*(-103) -130 + j*(-159) -64 + j*(-24) -124 + j*(-74) --255 + j*(204) -144 + j*(221) -28 + j*(-227) --13 + j*(278) -328 + j*(190) -253 + j*(482) -187 + j*(-18) --191 + j*(-597) -204 + j*(-31) --57 + j*(144) --252 + j*(-190) -221 + j*(-197) -35 + j*(139) -43 + j*(-66) --35 + j*(-119) -288 + j*(-279) -195 + j*(100) -215 + j*(312) --47 + j*(-114) --228 + j*(-92) -49 + j*(216) --376 + j*(82) --26 + j*(-35) -280 + j*(58) --412 + j*(-246) --158 + j*(-41) --95 + j*(316) -124 + j*(-209) --127 + j*(105) -69 + j*(89) --215 + j*(272) -88 + j*(-143) -112 + j*(-29) -69 + j*(40) --50 + j*(-23) -163 + j*(7) -69 + j*(-132) -60 + j*(115) -25 + j*(-206) --172 + j*(176) --535 + j*(-53) -141 + j*(52) -179 + j*(69) -65 + j*(29) -12 + j*(-180) --205 + j*(64) -82 + j*(136) -62 + j*(-64) -194 + j*(264) --332 + j*(177) --65 + j*(373) -34 + j*(107) --112 + j*(208) -140 + j*(-209) -269 + j*(4) --247 + j*(-40) --70 + j*(68) --179 + j*(-117) -102 + j*(-54) -148 + j*(-216) -446 + j*(35) -281 + j*(-202) --71 + j*(-89) -180 + j*(161) --77 + j*(-236) --33 + j*(-301) --11 + j*(-132) -71 + j*(-301) --94 + j*(43) --209 + j*(-148) -204 + j*(-35) -137 + j*(-66) -8 + j*(54) --186 + j*(-173) --82 + j*(-146) --218 + j*(-95) -202 + j*(-250) -212 + j*(-194) --2 + j*(-124) --425 + j*(190) --10 + j*(-141) --445 + j*(27) --66 + j*(-164) -13 + j*(-260) --109 + j*(132) -79 + j*(165) -39 + j*(259) -173 + j*(110) -35 + j*(264) --13 + j*(197) --47 + j*(-209) --219 + j*(-66) -93 + j*(142) --129 + j*(-158) -49 + j*(213) -270 + j*(57) --144 + j*(-371) --7 + j*(40) -276 + j*(-67) --144 + j*(94) --177 + j*(-30) --61 + j*(-129) --596 + j*(331) --67 + j*(214) --144 + j*(59) --301 + j*(-268) --146 + j*(-204) --117 + j*(-105) -90 + j*(24) --30 + j*(35) --166 + j*(-23) -92 + j*(-79) -106 + j*(-62) -127 + j*(400) --154 + j*(68) -31 + j*(354) -144 + j*(-104) -56 + j*(170) --74 + j*(25) --240 + j*(204) --111 + j*(-112) --57 + j*(69) -17 + j*(-59) --76 + j*(86) --168 + j*(262) --66 + j*(97) --360 + j*(224) --159 + j*(42) --131 + j*(-4) --68 + j*(-267) -110 + j*(151) --110 + j*(-136) --171 + j*(-18) --81 + j*(-235) --236 + j*(173) -378 + j*(-101) --203 + j*(47) -61 + j*(47) -12 + j*(349) -291 + j*(73) --470 + j*(73) -339 + j*(48) --1 + j*(-18) --132 + j*(-96) -86 + j*(63) --191 + j*(-190) --142 + j*(-22) --134 + j*(-180) --326 + j*(52) --198 + j*(-278) --88 + j*(146) --207 + j*(33) --192 + j*(-90) --55 + j*(-57) --156 + j*(64) --332 + j*(327) -235 + j*(-50) -65 + j*(373) -107 + j*(-127) -122 + j*(98) -123 + j*(-29) --61 + j*(-6) --35 + j*(58) -96 + j*(-22) -35 + j*(63) -123 + j*(-92) -172 + j*(-159) -240 + j*(57) --175 + j*(92) --87 + j*(-8) -122 + j*(-253) --236 + j*(-38) --163 + j*(300) --310 + j*(40) -87 + j*(-207) -454 + j*(68) --103 + j*(-186) -250 + j*(115) -474 + j*(156) -51 + j*(22) -31 + j*(2) -75 + j*(-193) --36 + j*(168) -162 + j*(-11) -86 + j*(187) --86 + j*(-121) -77 + j*(-82) -222 + j*(-158) --19 + j*(-135) -188 + j*(279) --4 + j*(198) -54 + j*(30) --199 + j*(173) -37 + j*(206) --16 + j*(359) -24 + j*(-164) -211 + j*(-117) -56 + j*(99) --17 + j*(32) -100 + j*(-287) --289 + j*(9) -122 + j*(158) -318 + j*(13) -59 + j*(-168) -78 + j*(218) --42 + j*(191) --202 + j*(-32) -74 + j*(99) --167 + j*(98) -64 + j*(343) -119 + j*(-105) --218 + j*(131) --116 + j*(-496) -44 + j*(267) --109 + j*(222) -42 + j*(40) --15 + j*(164) --74 + j*(308) --1 + j*(-144) --284 + j*(186) -146 + j*(-49) --244 + j*(240) --19 + j*(-161) -43 + j*(320) --136 + j*(20) -247 + j*(0) -69 + j*(-146) --141 + j*(400) --21 + j*(-227) -139 + j*(-40) -275 + j*(-26) --157 + j*(34) -28 + j*(83) --578 + j*(-7) --135 + j*(73) -76 + j*(148) --310 + j*(-154) -210 + j*(123) -52 + j*(-453) --257 + j*(14) -23 + j*(20) -130 + j*(202) -45 + j*(223) -299 + j*(-381) --103 + j*(-58) -39 + j*(40) --42 + j*(86) -161 + j*(-38) -129 + j*(-187) --84 + j*(-164) -8 + j*(-97) -110 + j*(172) -247 + j*(356) --310 + j*(-209) -46 + j*(13) -291 + j*(-132) -44 + j*(228) --43 + j*(166) --258 + j*(121) --17 + j*(-28) -327 + j*(-172) -336 + j*(153) -321 + j*(-74) -83 + j*(-168) -3 + j*(-115) -28 + j*(276) -124 + j*(-30) -88 + j*(-173) -341 + j*(-122) --32 + j*(288) -143 + j*(150) --389 + j*(-63) --136 + j*(4) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -]; diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 78acc373ee5ac3df3ad2d9822a6a7a400a5bb9d1..0f11447bf416da5476df5d257f26acc303d4b2bd 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -380,7 +380,7 @@ struct openair0_device_t { @param buff Buffer which holds the samples (2 dimensional) @param nsamps number of samples to be sent @param number of antennas - @param flags flags must be set to TRUE if timestamp parameter needs to be applied + @param flags flags must be set to true if timestamp parameter needs to be applied */ int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags); @@ -390,7 +390,7 @@ struct openair0_device_t { @param buff Buffer which holds the samples (1 dimensional) @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple anteannas - @param flags flags must be set to TRUE if timestamp parameter needs to be applied + @param flags flags must be set to true if timestamp parameter needs to be applied */ int (*trx_write_func2)(openair0_device *device, openair0_timestamp timestamp, void *buff, int nsamps,int antenna_id, int flags); diff --git a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp index 1273097f3b901468f6ffd56ff2737fcbf22114c0..47bbadfe2823544b094fe9ce916207b08a5ab869 100644 --- a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp +++ b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp @@ -134,7 +134,7 @@ static void trx_iris_end(openair0_device *device) { @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple anteannas - @param flags flags must be set to TRUE if timestamp parameter needs to be applied + @param flags flags must be set to true if timestamp parameter needs to be applied */ diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 89762843458452c97a672c2e63f602cea233461d..7c0180e5e789e6cdb3a02a5a2eea91930d5dc869 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -331,7 +331,7 @@ static void trx_usrp_end(openair0_device *device) { @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple antennas - @param flags flags must be set to TRUE if timestamp parameter needs to be applied + @param flags flags must be set to true if timestamp parameter needs to be applied */ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, @@ -352,7 +352,7 @@ static int trx_usrp_write(openair0_device *device, AssertFatal( MAX_WRITE_THREAD_BUFFER_SIZE >= cc,"Do not support more than %d cc number\n", MAX_WRITE_THREAD_BUFFER_SIZE); - boolean_t first_packet_state=false,last_packet_state=false; + bool first_packet_state=false,last_packet_state=false; if (flags_lsb == 2) { // start of burst // s->tx_md.start_of_burst = true; @@ -481,7 +481,7 @@ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_BEAM_SWITCHI @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple antennas - @param flags flags must be set to TRUE if timestamp parameter needs to be applied + @param flags flags must be set to true if timestamp parameter needs to be applied */ void *trx_usrp_write_thread(void * arg){ int ret=0; @@ -675,7 +675,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp } if (samples_received == nsamps) s->wait_for_first_pps=0; - // bring RX data into 12 LSBs for softmodem RX + // bring RX data into 12 LSBs for softmodem RX for (int i=0; i<cc; i++) { #if defined(__x86_64__) || defined(__i386__) @@ -1030,9 +1030,13 @@ extern "C" { } if (device_adds[0].get("type") == "n3xx") { - printf("Found USRP n300\n"); + const std::string product = device_adds[0].get("product"); + printf("Found USRP %s\n", product.c_str()); device->type=USRP_N300_DEV; - usrp_master_clock = 122.88e6; + if (product == "n320") + usrp_master_clock = 245.76e6; // N320 does not support 122.88e6 master clock rate + else + usrp_master_clock = 122.88e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); if ( 0 != system("sysctl -w net.core.rmem_max=62500000 net.core.wmem_max=62500000") ) diff --git a/targets/ARCH/iqplayer/iqplayer_lib.c b/targets/ARCH/iqplayer/iqplayer_lib.c index b62c1935d36967c88da984536846a60b9a9f7ca0..f6578d6e9a31707b3b0220465bb47bf7048b1615 100644 --- a/targets/ARCH/iqplayer/iqplayer_lib.c +++ b/targets/ARCH/iqplayer/iqplayer_lib.c @@ -158,7 +158,7 @@ static void trx_iqplayer_end(openair0_device *device) { @param buff Buffer which holds the samples @param nsamps number of samples to be sent @param antenna_id index of the antenna if the device has multiple antennas - @param flags flags must be set to TRUE if timestamp parameter needs to be applied + @param flags flags must be set to true if timestamp parameter needs to be applied */ static int trx_iqplayer_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { struct timespec req; diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c index cf025680cd76d3665135a2002a9c5e5ad35158f4..17ab3cb734391e417dda4793993f1fddfac353c4 100644 --- a/targets/ARCH/rfsimulator/stored_node.c +++ b/targets/ARCH/rfsimulator/stored_node.c @@ -187,7 +187,7 @@ int main(int argc, char *argv[]) { } uint64_t typeStamp=ENB_MAGICDL; - boolean_t raw=false; + bool raw = false; if ( argc == 5 ) { raw=true; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf index d14267dcd84f89441248b2655789c433c8a7f268..c8e109d30230f435ee788e4d49a1893ae3dc8b33 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/benetel-5g.conf @@ -22,7 +22,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf index 52e4eec30e89325f4eb7f246441ff4cf6e9eb2e7..a4c877a7bafcb46427cdad068e1c89054929d802 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf index ab435c9686684d4b97a7b58d017dbd300eea48ee..e5478983cff20909524743e70280d66148b8ac8c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf index a04e0e6123f398948b5bd9f85345998f83a2c0d0..efa0d3e2fa0db1266a8ae08c54087acacb632528 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf index 426f9e782b1a0cc3196af816495c936646b0828e..8a2ce9f63ecc361c7de47e3508384c64e6eaf1f1 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band261.tm1.32PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf index 216728577a775fb8db3a4375894753ba49c3435f..616f86a1cd6a5fbb9d8ce94337895c16e1f851af 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf index 59d466656c66319d08cec18df5c3d9619b20c907..0818fe11d7c8f926711b7c34fd42f16876065d58 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.106PRB.usrpx300.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.25PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.25PRB.usrpn300.conf index 6af135608888ea1f106e839710851e7c26fa4ca2..022f17e490e140b335f1443b9470bca5bfb0f4d5 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.25PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band66.tm1.25PRB.usrpn300.conf @@ -21,9 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 1; - pusch_AntennaPorts = 1; min_rxtxtime = 6; servingCellConfigCommon = ( diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf index 2ae4df07d9c80b3bc2dff2ee4414799279cbcef1..5c636af06c001cd9e128623d6c136a041b151e91 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.30kHz,usrpb2x0.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf index 21267870bd5e8b468c41afe7fcdd2b2cab91290e..812ac8dafbcb3924ea8cd496fcd3d0ad224f584b 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf index a0fd0bda9f0221dc5c36419a17e9add1fa8f26bf..781384a78915352dfa064611a73a34f3511a530f 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.slave.conf @@ -20,8 +20,6 @@ gNBs = tr_s_preference = "local_mac" ////////// Physical parameters: - - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf index 5c8f90d9b5555a1ce02aa3ee8c3743c3d9c20b6f..1450c45eee0830a579a4b481375a3246346ec4ae 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.PTRS.usrpx300.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf index 7bf3626870a6604c8a6c576347ceb7425ce6c386..562e2b16ab0e66c4d02e342892943f9a76fd1576 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpb210.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 909c54b858b5042ce33a250132cdaa7dbf881365..a8ecb8c4b6783ba5c29cfc9c16e88a85eb969918 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index d0f394be16a648c0efba3d26bd474647f435e674..10122b9eb2c7a9927e0aad416d0a07281735938c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index 0438e61337210d1e37ec783d253b983f41d40e26..20d01c2a00d9663cdf4cbfaa3adc9068a2e8f532 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -20,8 +20,6 @@ gNBs = tr_s_preference = "local_mac" ////////// Physical parameters: - - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf index 66c2151eb83997cabe07d0016c269a01b71c9a10..44f3889eece0e356be101ae7b6bba7e55c386741 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf index c6ea066fc48aa0c9dae1d446f9f4d6962d438373..fbafef81b412d1fd5637f60d689effc07ebbdcc5 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpb210.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf index fcfe58a3c024e059e0417d927962531f6c16e4c6..38d6ed3c610193880649eb047f283b0265cfd2c6 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf index 2ad9757cb132fa517500d2d746d4c09572ec08c3..b7da7b17f4bd80d52c93652ea07e71b2bb4501bb 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.24PRB.usrpx300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf index 44074f3fd91e18a00bfe60080484594be6014ecf..9f78716bcc20c4e802d6bb5c1a9bb3855035303a 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf index 7ce150506f0da42c6f2f5c67763e1ce347004dd3..1dcef89736833fcad566bdde7fc6bbb62a06d0e5 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band78.tm1.106PRB.nfapi.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf index 306e652eaa9b5d1e763b3d0e97867173d03565e1..9a3fe358a54a80e534f5941432c46766aeb4312d 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf index d08c0f14a08ad55c3b0c30daf6388c416ab59cc4..9e1ae24d673fbf59d3dfae94235f22b32b42c029 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_24PRB.conf @@ -21,8 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; - servingCellConfigCommon = ( { #spCellConfigCommon diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf index e3204db8faeb657aca5ea06d1da289c947266351..9ec28b93e700ece3cbbeca0b722bfdeee0295d48 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_n310.conf @@ -20,8 +20,6 @@ gNBs = tr_s_preference = "local_mac" ////////// Physical parameters: - - ssb_SubcarrierOffset = 31; //0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf index 030dc102267bafc37ce9a97b16d57cad20ae0737..35778ef7059023e9d9e8a0d909453b71c44005a2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/testing_gnb_nsa_n310.conf @@ -21,7 +21,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 31; //0; pusch_TargetSNRx10 = 200; pucch_TargetSNRx10 = 200; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf index 6aacd98c7f041c1fd1f853fbf5115350938df4b3..a64a4c6022e76595cd461342895c584890dbcfb9 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/cu_gnb.conf @@ -44,7 +44,6 @@ gNBs = local_s_portd = 2152; remote_s_portc = 500; remote_s_portd = 2152; - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf index f95bdf91aee97e2c4c02f8b89db251622bacaf0c..4309c13dd395a172e589e66b4efc469e585fbf04 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf @@ -36,7 +36,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf index f91683897f75619a36907f455703a185ec6f985c..cb90889b52fc48fc07be9543fccc43251e6a443e 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.band78.tm1.106PRB.usrpn300.gtp-itti.conf @@ -36,7 +36,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; servingCellConfigCommon = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf index cd84e699c77f6a6ae14b257723564ceb24742f48..42aa555771283bbf5a12c70ca41273c95efce993 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf @@ -28,9 +28,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - min_rxtxtime = 2; - do_CSIRS = 1; do_SRS = 1; pdcch_ConfigSIB1 = ( @@ -342,4 +339,7 @@ log_config : ngap_log_level ="debug"; f1ap_log_level ="debug"; }; +<<<<<<< HEAD +======= +>>>>>>> origin/develop diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf index ff64fe718af859c0320bb3d6cbba4124be26f906..6abf2c19cc66459be3751be772079e746202eef8 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band66.fr1.106PRB.usrpn300.conf @@ -32,9 +32,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 1; - pusch_AntennaPorts = 1; min_rxtxtime = 6; pdcch_ConfigSIB1 = ( diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf index ef34e68934972bf26185331b6779bc2d18c81abd..30be59725586db3ac6df179a5e862de4bcb30021 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf @@ -28,7 +28,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_N1 = 2; pusch_AntennaPorts = 2; do_CSIRS = 1; @@ -266,6 +265,7 @@ MACRLCs = ( tr_n_preference = "local_RRC"; #pusch_TargetSNRx10 = 150; #pucch_TargetSNRx10 = 200; + ul_prbblack_SNR_threshold = 10; ulsch_max_frame_inactivity = 0; } ); diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf index 74f2f9c11cefdc81114045dad5d9d2e5321dff50..8ff83b5d023abaf757517e48c1c2c28ab62db92e 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.4layer.conf @@ -32,10 +32,9 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 4; + pdsch_AntennaPorts_XP = 2; + pdsch_AntennaPorts_N1 = 2; pusch_AntennaPorts = 4; - sib1_tda = 0; pdcch_ConfigSIB1 = ( { @@ -73,15 +72,6 @@ gNBs = #pdcch-ConfigCommon initialDLBWPcontrolResourceSetZero = 12; initialDLBWPsearchSpaceZero = 0; - #pdsch-ConfigCommon - #pdschTimeDomainAllocationList (up to 16 entries) - initialDLBWPk0_0 = 0; #for DL slot - initialDLBWPmappingType_0 = 0; #0=typeA,1=typeB - initialDLBWPstartSymbolAndLength_0 = 40; #this is SS=1,L=13 - - initialDLBWPk0_1 = 0; #for mixed slot - initialDLBWPmappingType_1 = 0; - initialDLBWPstartSymbolAndLength_1 = 57; #this is SS=1,L=5 #uplinkConfigCommon #frequencyInfoUL @@ -136,19 +126,6 @@ gNBs = # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, - # pusch-ConfigCommon (up to 16 elements) - initialULBWPk2_0 = 6; # used for UL slot - initialULBWPmappingType_0 = 1 - initialULBWPstartSymbolAndLength_0 = 41; # this is SS=0 L=13 - - initialULBWPk2_1 = 6; # used for mixed slot - initialULBWPmappingType_1 = 1; - initialULBWPstartSymbolAndLength_1 = 52; # this is SS=10 L=4 - - initialULBWPk2_2 = 7; # used for Msg.3 during RA - initialULBWPmappingType_2 = 1; - initialULBWPstartSymbolAndLength_2 = 52; # this is SS=10 L=4 - msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf index eceb7c1755cf81351f9daa8c5f9afe845b9b14a3..9d00ae20aa8388bcffd92528ca17857aeaf6be3e 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf @@ -28,7 +28,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; min_rxtxtime = 2; do_CSIRS = 1; do_SRS = 1; @@ -264,6 +263,7 @@ MACRLCs = ( tr_n_preference = "local_RRC"; pusch_TargetSNRx10 = 150; pucch_TargetSNRx10 = 200; + ul_prbblack_SNR_threshold = 10; ulsch_max_frame_inactivity = 0; } ); diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf index 8ca0c0887692f7c0a0747556334c245cfc1e4cab..6719a5534d43e8a522760c81119d954343418362 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.sabox.conf @@ -30,7 +30,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdcch_ConfigSIB1 = ( { diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf index e3ecf87ca07bb44ae8d0b31fa08e220a4f62d616..5f8bf4523217874bad01d9c49610af90a0aa3748 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.162PRB.2x2.usrpn300.conf @@ -27,7 +27,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 1; pusch_AntennaPorts = 2; do_CSIRS = 0; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf index 763396998d2f0c6ef61fbb222b8dbe75f3ad7226..1f1f64ce3ffde83f7515b3bb247949108ca3c3f5 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.217PRB.2x2.usrpn300.conf @@ -27,7 +27,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 1; pusch_AntennaPorts = 2; do_CSIRS = 0; @@ -318,4 +317,4 @@ log_config : rrc_log_level ="info"; ngap_log_level ="debug"; f1ap_log_level ="debug"; -}; \ No newline at end of file +}; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf index bd3076a014cc9d75098288ca4c0cca05cb8b0d29..ad1471339a249a39b5308b122f7b864a7b4db5c3 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.24PRB.usrpb210.conf @@ -32,9 +32,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; - pdsch_AntennaPorts = 1; - pusch_AntennaPorts = 1; sib1_tda = 15; min_rxtxtime = 6; diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.273PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.273PRB.2x2.usrpn300.conf index 3d93f2cfaba649ec8b0967cf567d63ff67f7f43b..24090bef85b1fcb305d3ebedbfac4c18276792b4 100644 --- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.273PRB.2x2.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.273PRB.2x2.usrpn300.conf @@ -27,7 +27,6 @@ gNBs = ////////// Physical parameters: - ssb_SubcarrierOffset = 0; pdsch_AntennaPorts_XP = 1; pusch_AntennaPorts = 2; do_CSIRS = 0; @@ -318,4 +317,4 @@ log_config : rrc_log_level ="info"; ngap_log_level ="debug"; f1ap_log_level ="debug"; -}; \ No newline at end of file +}; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index a3048995a53f1de81d41aff08a83848eb698d52c..3d62d5c19ad5928afcee0719f71c23c77486bb98 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -231,9 +231,9 @@ static inline int rxtx(PHY_VARS_eNB *eNB, dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use; // L2-emulator can work only one eNB. // memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); - // memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + // memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.active, sizeof(bool)*NUMBER_OF_UE_MAX); memcpy(&pre_scd_eNB_UE_stats,&RC.mac[0]->UE_info.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); - memcpy(&pre_scd_activeUE, &RC.mac[0]->UE_info.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + memcpy(&pre_scd_activeUE, &RC.mac[0]->UE_info.active, sizeof(bool)*NUMBER_OF_UE_MAX); AssertFatal((ret= pthread_mutex_lock(&ru->proc.mutex_pre_scd))==0,"[eNB] error locking proc mutex for eNB pre scd, return %d\n",ret); ru->proc.instance_pre_scd++; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 836709b473c76334760d2e703bfd8dcce715a1b2..1d464cb90c4b66433bb9ee48fce9dd4e438c5a3b 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -89,7 +89,7 @@ void prach_procedures(PHY_VARS_eNB *eNB,int br_flag); void stop_RU(RU_t **rup,int nb_ru); -void do_ru_synch(RU_t *ru); +static void do_ru_synch(RU_t *ru); void configure_ru(int idx, void *arg); @@ -1059,7 +1059,7 @@ int wakeup_synch(RU_t *ru) { } -void do_ru_synch(RU_t *ru) { +static void do_ru_synch(RU_t *ru) { LTE_DL_FRAME_PARMS *fp = ru->frame_parms; RU_proc_t *proc = &ru->proc; int rxs, ic, ret, i; @@ -1834,7 +1834,7 @@ static void *ru_thread( void *param ) { new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use; dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use; memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); - memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_info.active, sizeof(bool)*NUMBER_OF_UE_MAX); AssertFatal((ret=pthread_mutex_lock(&ru->proc.mutex_pre_scd))==0,"[eNB] error locking proc mutex for eNB pre scd\n"); ru->proc.instance_pre_scd++; @@ -1924,7 +1924,7 @@ static void *ru_thread( void *param ) { // This thread run the initial synchronization like a UE -void *ru_thread_synch(void *arg) { +static void *ru_thread_synch(void *arg) { RU_t *ru = (RU_t *)arg; __attribute__((unused)) LTE_DL_FRAME_PARMS *fp = ru->frame_parms; diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 1c887dd3c8ee4652fa9ac7d7335ce2557bf67e7f..38b71238b828929a990e30bdca7d5bae58ae945b 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -29,6 +29,7 @@ #include "flexran_agent.h" #include "s1ap_eNB.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" +#include "targets/ARCH/COMMON/common_lib.h" #include "executables/softmodem-common.h" @@ -213,5 +214,19 @@ extern void init_UE_standalone_thread(int ue_idx); extern PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); extern void init_bler_table(void); - +void feptx_ofdm_2thread(RU_t *ru, + int frame, + int subframe); +void* ru_thread_control( void* param ); +void wait_eNBs(void); +void kill_feptx_thread(RU_t *ru); +void init_fep_thread(RU_t *ru, pthread_attr_t *attr_fep); +void init_feptx_thread(RU_t *ru, pthread_attr_t *attr_feptx); +void fep_full(RU_t *ru, int subframe); +void configure_ru(int, void *arg); +void configure_rru(int, void *arg); +void ru_fep_full_2thread(RU_t *ru,int subframe); +void feptx_ofdm(RU_t*ru, int frame_tx, int tti_tx); +void feptx_prec(struct RU_t_s *ru, int frame_tx, int tti_tx); +void fill_rf_config(RU_t *ru, char *rf_config_file); #endif diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 678b6e0401cb81d846e4b8d65989257e04e8d6c8..05602b63da6ce068a4a02397b429a35d87d192d7 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -176,7 +176,6 @@ extern char uecap_xer[1024]; char uecap_xer_in=0; int oaisim_flag=0; -//threads_t threads= {-1,-1,-1,-1,-1,-1,-1,-1}; /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed * this is very hackish - find a proper solution diff --git a/targets/TEST/PDCP/test_pdcp.c b/targets/TEST/PDCP/test_pdcp.c index b62edf1215410921f3c9e27fbe7d4c55b9400fd3..d6becf87c1499167d1399a0ea8c6defa7cd1a8ac 100644 --- a/targets/TEST/PDCP/test_pdcp.c +++ b/targets/TEST/PDCP/test_pdcp.c @@ -100,7 +100,7 @@ int main(int argc, char **argv) list_init(&test_pdu_rx_list, NULL); logInit(); - if (init_pdcp_entity(&pdcp_array[0]) == TRUE && init_pdcp_entity(&pdcp_array[1]) == TRUE) + if (init_pdcp_entity(&pdcp_array[0]) == true && init_pdcp_entity(&pdcp_array[1]) == true) msg("[TEST] PDCP entity initialization OK\n"); else { msg("[TEST] Cannot initialize PDCP entities!\n"); @@ -109,7 +109,7 @@ int main(int argc, char **argv) /* Initialize PDCP state variables */ for (index = 0; index < 2; ++index) { - if (pdcp_init_seq_numbers(&pdcp_array[index]) == FALSE) { + if (pdcp_init_seq_numbers(&pdcp_array[index]) == false) { msg("[TEST] Cannot initialize sequence numbers of PDCP entity %d!\n", index); exit(1); } else { @@ -120,11 +120,11 @@ int main(int argc, char **argv) #if TEST_RX_AND_TX_WINDOW /* Test TX window */ - if (test_tx_window() == FALSE) + if (test_tx_window() == false) test_result = 1; /* Test RX window */ - if (test_rx_window() == FALSE) + if (test_rx_window() == false) test_result = 1; #endif @@ -132,11 +132,11 @@ int main(int argc, char **argv) #if TEST_PDCP_DATA_REQUEST_AND_INDICATION /* Test pdcp_data_req() method in pdcp.c */ - if (test_pdcp_data_req() == FALSE) + if (test_pdcp_data_req() == false) test_result = 1; /* Test pdcp_data_ind() method in pdcp.c */ - if (test_pdcp_data_ind() == FALSE) + if (test_pdcp_data_ind() == false) test_result = 1; #endif @@ -150,10 +150,10 @@ int main(int argc, char **argv) return test_result; } -BOOL init_pdcp_entity(pdcp_t *pdcp_entity) +bool init_pdcp_entity(pdcp_t *pdcp_entity) { if (pdcp_entity == NULL) - return FALSE; + return false; /* * Initialize sequence number state variables of relevant PDCP entity @@ -171,10 +171,10 @@ BOOL init_pdcp_entity(pdcp_t *pdcp_entity) pdcp_entity->next_pdcp_rx_sn, pdcp_entity->tx_hfn, pdcp_entity->rx_hfn, \ pdcp_entity->last_submitted_pdcp_rx_sn, pdcp_entity->seq_num_size); - return TRUE; + return true; } -BOOL test_tx_window(void) +bool test_tx_window(void) { unsigned long index = 0; @@ -185,33 +185,33 @@ BOOL test_tx_window(void) msg("TX packet # %07lu seq # %04d hfn # %04d\n", index, pseudo_tx_sn, pdcp_array[0].tx_hfn); else { msg("TX packet is out-of-window!\n"); - return FALSE; + return false; } } - return TRUE; + return true; } -BOOL test_rx_window(void) +bool test_rx_window(void) { unsigned long index = 0; for (index = 0; index < NUMBER_OF_TEST_PACKETS; ++index) { u16 pseudo_rx_sn = (index == 0) ? 0 : index % WINDOW_SIZE; - if (pdcp_is_rx_seq_number_valid(pseudo_rx_sn, &pdcp_array[1]) == TRUE) { + if (pdcp_is_rx_seq_number_valid(pseudo_rx_sn, &pdcp_array[1]) == true) { msg("RX packet # %07lu seq # %04d last-submitted # %04d hfn # %04d\n", \ index, pdcp_array[1].next_pdcp_rx_sn, pdcp_array[1].last_submitted_pdcp_rx_sn, pdcp_array[1].rx_hfn); } else { msg("RX packet seq # %04lu is not valid!\n", index); - return FALSE; + return false; } } - return TRUE; + return true; } -BOOL test_pdcp_data_req(void) +bool test_pdcp_data_req(void) { unsigned char* pdcp_test_pdu_buffer = NULL; unsigned char pdcp_test_pdu_buffer_size = DUMMY_BUFFER_SIZE + PDCP_USER_PLANE_DATA_PDU_LONG_SN_HEADER_SIZE; @@ -224,7 +224,7 @@ BOOL test_pdcp_data_req(void) if (pdcp_test_pdu_buffer == NULL) { msg("Cannot allocate a buffer for test!\n"); - return FALSE; + return false; } /* @@ -241,7 +241,7 @@ BOOL test_pdcp_data_req(void) /* * Ask PDCP to create a PDU with given buffer and enqueue it to `test_pdu_tx_list` */ - if (pdcp_data_req(0, 0, 10, DUMMY_BUFFER, &pdcp_array[0], &test_pdu_tx_list) == TRUE) { + if (pdcp_data_req(0, 0, 10, DUMMY_BUFFER, &pdcp_array[0], &test_pdu_tx_list) == true) { msg("[TEST] Starting to dissect PDU created by PDCP...\n"); /* @@ -251,7 +251,7 @@ BOOL test_pdcp_data_req(void) if (pdcp_test_pdu_buffer_size == 0 ) { msg("[TEST] PDU created by pdcp_data_req() is invalid!\n"); - return FALSE; + return false; } /* @@ -269,7 +269,7 @@ BOOL test_pdcp_data_req(void) */ if (pdcp_test_pdu_buffer[0] & 0x80) { msg("[TEST] First bit is not 0, which means this is not a Data PDU!\n"); - return FALSE; + return false; } else { msg("[TEST] First bit is 0 so this is a Data PDU, OK\n"); } @@ -279,7 +279,7 @@ BOOL test_pdcp_data_req(void) */ if ((pdcp_test_pdu_buffer[0] & 0x70) != 0) { msg("[TEST] Reserved bits are not 0!\n"); - return FALSE; + return false; } else { msg("[TEST] Reserved bits are all 0, OK\n"); } @@ -292,21 +292,21 @@ BOOL test_pdcp_data_req(void) if (sequence_number != index % WINDOW_SIZE) { msg("[TEST] Sequence numbers are out-of-order!\n"); - return FALSE; + return false; } else { msg("[TEST] Sequence number is correct\n"); } } else { msg("[TEST] pdcp_data_req() returned FALSE!\n"); - return FALSE; + return false; } } - return TRUE; + return true; } -BOOL test_pdcp_data_ind(void) +bool test_pdcp_data_ind(void) { /* * This is the list that pdcp_data_ind() takes to put pdcp_data_ind_header_t @@ -341,9 +341,9 @@ BOOL test_pdcp_data_ind(void) test_sdu = list_remove_head(&test_pdu_rx_list); - if (pdcp_data_ind(0, 0, test_sdu_size, test_sdu, &pdcp_array[0], &test_pdu_indication_list) == FALSE) { + if (pdcp_data_ind(0, 0, test_sdu_size, test_sdu, &pdcp_array[0], &test_pdu_indication_list) == false) { msg("[TEST] pdcp_data_ind() failed to handle data indication!\n"); - return FALSE; + return false; } else { msg("[TEST] pdcp_data_ind() succcessfuly handled data indication\n"); } @@ -359,7 +359,7 @@ BOOL test_pdcp_data_ind(void) if (test_data_ind_header == NULL) { msg("[TEST] Data indication header is not valid!\n"); - return FALSE; + return false; } else { pdcp_data_ind_header_t* indication_header = (pdcp_data_ind_header_t*)test_data_ind_header->data; @@ -370,7 +370,7 @@ BOOL test_pdcp_data_ind(void) msg("[TEST] Radio bearer ID is correct\n"); } else { msg("[TEST] Radio bearer ID is not correct! (expected: 0, parsed: %d)\n", indication_header->rb_id); - return FALSE; + return false; } /* @@ -380,7 +380,7 @@ BOOL test_pdcp_data_ind(void) msg("[TEST] SDU size is correct\n"); } else { msg("[TEST] SDU size is not correct! (expected: %d, parsed: %d)\n", DUMMY_BUFFER_SIZE, indication_header->data_size); - return FALSE; + return false; } /* @@ -412,11 +412,11 @@ BOOL test_pdcp_data_ind(void) print_byte_stream("[TEST] TXed data: ", DUMMY_BUFFER, DUMMY_BUFFER_SIZE); print_byte_stream("[TEST] RXed data: ", (unsigned char*)&(test_data_ind_header->data[data_index]), DUMMY_BUFFER_SIZE); - return FALSE; + return false; } } - return TRUE; + return true; } diff --git a/targets/TEST/PDCP/test_pdcp.h b/targets/TEST/PDCP/test_pdcp.h index 0da174cc8caad238452240d5bc70bcf435901a1d..629f6f253910bf5e69fe8767005e7a2328829782 100644 --- a/targets/TEST/PDCP/test_pdcp.h +++ b/targets/TEST/PDCP/test_pdcp.h @@ -42,17 +42,17 @@ int pdcp_fifo_flush_sdus (void) { return 0; } int pdcp_fifo_read_input_sdus_remaining_bytes (void) { return 0; } int pdcp_fifo_read_input_sdus (void) { return 0; } -BOOL init_pdcp_entity(pdcp_t *pdcp_entity); -BOOL test_tx_window(void); -BOOL test_rx_window(void); -BOOL test_pdcp_data_req(void); -BOOL test_pdcp_data_ind(void); +bool init_pdcp_entity(pdcp_t *pdcp_entity); +bool test_tx_window(void); +bool test_rx_window(void); +bool test_pdcp_data_req(void); +bool test_pdcp_data_ind(void); /* * PDCP methods that are going to be utilised throughout the test */ -extern BOOL pdcp_init_seq_numbers(pdcp_t* pdcp_entity); +extern bool pdcp_init_seq_numbers(pdcp_t* pdcp_entity); extern u16 pdcp_get_next_tx_seq_number(pdcp_t* pdcp_entity); -extern BOOL pdcp_is_rx_seq_number_valid(u16 seq_num, pdcp_t* pdcp_entity); +extern bool pdcp_is_rx_seq_number_valid(u16 seq_num, pdcp_t* pdcp_entity); #endif diff --git a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c index 378ee95c3bea10fbf8b4a019fb788dd4208184fa..7b8017172435300c4d3ef7a4044724263d90f1d3 100644 --- a/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c +++ b/targets/TEST/PDCP/with_rlc/test_pdcp_rlc.c @@ -109,7 +109,7 @@ int pdcp_fifo_flush_sdus () {} int pdcp_fifo_read_input_sdus_remaining_bytes () {} int pdcp_fifo_read_input_sdus () {} -BOOL init_pdcp_entity(pdcp_t *pdcp_entity); +bool init_pdcp_entity(pdcp_t *pdcp_entity); //----------------------------------------------------------------------------- void pdcp_rlc_test_mac_rlc_loop (struct mac_data_ind *data_indP, struct mac_data_req *data_requestP, int* drop_countP, int *tx_packetsP, int* dropped_tx_packetsP) //----------------------------------------------------------------------------- @@ -230,7 +230,7 @@ int main(int argc, char **argv) pdcp_module_init(); logInit(); - if (init_pdcp_entity(&pdcp_array[0][1]) == TRUE && init_pdcp_entity(&pdcp_array[1][1]) == TRUE) + if (init_pdcp_entity(&pdcp_array[0][1]) == true && init_pdcp_entity(&pdcp_array[1][1]) == true) msg("PDCP entity initialization OK\n"); else { msg("Cannot initialize PDCP entities!\n"); @@ -239,7 +239,7 @@ int main(int argc, char **argv) /* Initialize PDCP state variables */ for (index = 0; index < 2; ++index) { - if (pdcp_init_seq_numbers(&pdcp_array[index][1]) == FALSE) { + if (pdcp_init_seq_numbers(&pdcp_array[index][1]) == false) { msg("Cannot initialize %s PDCP entity!\n", ((index == 0) ? "first" : "second")); exit(1); } @@ -275,11 +275,11 @@ int main(int argc, char **argv) } //----------------------------------------------------------------------------- -BOOL init_pdcp_entity(pdcp_t *pdcp_entity) +bool init_pdcp_entity(pdcp_t *pdcp_entity) //----------------------------------------------------------------------------- { if (pdcp_entity == NULL) - return FALSE; + return false; /* * Initialize sequence number state variables of relevant PDCP entity @@ -292,6 +292,6 @@ BOOL init_pdcp_entity(pdcp_t *pdcp_entity) pdcp_entity->last_submitted_pdcp_rx_sn = 4095; pdcp_entity->seq_num_size = 12; - return TRUE; + return true; } diff --git a/txsig0.m b/txsig0.m deleted file mode 100644 index e795208a15a299557be7280830ba630e20587996..0000000000000000000000000000000000000000 --- a/txsig0.m +++ /dev/null @@ -1,61441 +0,0 @@ -txs0 = [-194 + j*(-202) --136 + j*(186) -248 + j*(59) -61 + j*(-331) --327 + j*(-134) --161 + j*(205) -70 + j*(64) --84 + j*(-35) --82 + j*(168) -170 + j*(116) -105 + j*(-159) --163 + j*(-94) --102 + j*(147) -100 + j*(89) -31 + j*(-79) --114 + j*(4) --25 + j*(144) -112 + j*(64) -41 + j*(-65) --84 + j*(9) --18 + j*(151) -137 + j*(129) -190 + j*(9) -163 + j*(-89) -85 + j*(-173) --68 + j*(-154) --93 + j*(26) -119 + j*(64) -183 + j*(-209) --139 + j*(-343) --365 + j*(-29) --107 + j*(252) -180 + j*(51) -11 + j*(-232) --279 + j*(-96) --200 + j*(193) -42 + j*(170) -37 + j*(-5) --93 + j*(13) --81 + j*(137) -21 + j*(187) -158 + j*(174) -303 + j*(-10) -155 + j*(-324) --275 + j*(-277) --348 + j*(180) -57 + j*(327) -197 + j*(1) --89 + j*(-71) --107 + j*(244) -254 + j*(283) -382 + j*(-61) -137 + j*(-263) --69 + j*(-141) --19 + j*(32) -138 + j*(8) -135 + j*(-159) --20 + j*(-175) --9 + j*(-51) -126 + j*(-153) --52 + j*(-384) --409 + j*(-234) --389 + j*(165) --78 + j*(276) -81 + j*(133) -94 + j*(11) -42 + j*(-99) --103 + j*(-112) --155 + j*(25) --57 + j*(74) --47 + j*(23) --64 + j*(69) -36 + j*(51) --16 + j*(-105) --230 + j*(-46) --211 + j*(189) --51 + j*(221) --39 + j*(208) -67 + j*(312) -308 + j*(188) -240 + j*(-112) --30 + j*(-91) --16 + j*(126) -153 + j*(117) -170 + j*(12) -156 + j*(-11) -173 + j*(-64) -130 + j*(-112) -123 + j*(-123) -100 + j*(-220) --86 + j*(-247) --170 + j*(-43) -21 + j*(40) -64 + j*(-161) --175 + j*(-176) --196 + j*(100) -91 + j*(138) -151 + j*(-144) --111 + j*(-234) --230 + j*(-19) --85 + j*(96) --11 + j*(9) --78 + j*(-10) --66 + j*(57) --17 + j*(30) --70 + j*(21) --45 + j*(133) -139 + j*(109) -154 + j*(-121) --70 + j*(-189) --165 + j*(-28) --98 + j*(46) --93 + j*(60) --33 + j*(136) -93 + j*(59) --5 + j*(-81) --144 + j*(55) -36 + j*(194) -176 + j*(-16) --49 + j*(-146) --166 + j*(75) -32 + j*(179) -109 + j*(33) -25 + j*(9) -74 + j*(42) -80 + j*(-77) --93 + j*(-79) --105 + j*(128) -111 + j*(162) -170 + j*(-36) --4 + j*(-98) --60 + j*(74) -142 + j*(148) -281 + j*(-80) -70 + j*(-296) --184 + j*(-135) --49 + j*(103) -166 + j*(-62) --46 + j*(-301) --354 + j*(-80) --202 + j*(281) -147 + j*(244) -206 + j*(-15) -78 + j*(-109) -20 + j*(-95) --17 + j*(-116) --112 + j*(-98) --159 + j*(30) --44 + j*(146) -110 + j*(66) -59 + j*(-88) --69 + j*(-35) -13 + j*(67) -104 + j*(-51) --37 + j*(-129) --83 + j*(6) -40 + j*(-13) --67 + j*(-129) --181 + j*(74) -120 + j*(185) -238 + j*(-213) --223 + j*(-363) --411 + j*(107) --2 + j*(288) -109 + j*(-43) --169 + j*(-46) --73 + j*(214) -182 + j*(56) --7 + j*(-186) --223 + j*(5) --57 + j*(177) -38 + j*(27) --137 + j*(19) --122 + j*(259) -152 + j*(303) -272 + j*(86) -172 + j*(-42) -145 + j*(-28) -195 + j*(-117) -64 + j*(-272) --177 + j*(-182) --171 + j*(71) -32 + j*(98) -31 + j*(-51) --99 + j*(11) -8 + j*(153) -159 + j*(35) -35 + j*(-93) --64 + j*(65) -149 + j*(186) -355 + j*(-29) -238 + j*(-317) --43 + j*(-356) --204 + j*(-183) --149 + j*(-11) --34 + j*(-13) --62 + j*(-84) --139 + j*(-6) --34 + j*(103) -103 + j*(-2) -18 + j*(-142) --96 + j*(-79) --27 + j*(-25) --26 + j*(-159) --263 + j*(-175) --385 + j*(125) --127 + j*(377) -177 + j*(252) -168 + j*(13) -60 + j*(5) -144 + j*(21) -160 + j*(-194) --136 + j*(-288) --318 + j*(5) --82 + j*(217) -93 + j*(27) --91 + j*(-98) --199 + j*(90) --41 + j*(188) -8 + j*(95) --67 + j*(132) -27 + j*(257) -204 + j*(201) -247 + j*(55) -214 + j*(-49) -131 + j*(-134) --10 + j*(-97) -16 + j*(65) -221 + j*(31) -221 + j*(-237) --64 + j*(-323) --230 + j*(-107) --126 + j*(61) --33 + j*(42) --40 + j*(42) -20 + j*(91) -120 + j*(29) -89 + j*(-100) --38 + j*(-103) --58 + j*(13) -58 + j*(46) -122 + j*(-83) -0 + j*(-199) --163 + j*(-120) --140 + j*(45) --11 + j*(53) --18 + j*(-31) --82 + j*(17) -11 + j*(74) -59 + j*(-59) --120 + j*(-101) --171 + j*(128) -76 + j*(203) -172 + j*(-20) -10 + j*(-92) -9 + j*(9) -75 + j*(-86) --111 + j*(-147) --175 + j*(105) -122 + j*(173) -203 + j*(-151) --111 + j*(-262) --245 + j*(-17) --110 + j*(93) --74 + j*(53) --79 + j*(90) --29 + j*(81) --96 + j*(72) --87 + j*(255) -197 + j*(303) -325 + j*(8) -103 + j*(-132) -39 + j*(30) -215 + j*(1) -166 + j*(-223) --55 + j*(-224) --98 + j*(-93) --86 + j*(-68) --130 + j*(-1) --34 + j*(97) -81 + j*(-18) --69 + j*(-147) --237 + j*(30) --83 + j*(245) -132 + j*(166) -120 + j*(25) -91 + j*(37) -170 + j*(-23) -83 + j*(-180) --124 + j*(-100) --45 + j*(129) -206 + j*(34) -113 + j*(-245) --176 + j*(-175) --128 + j*(87) -92 + j*(37) -29 + j*(-153) --144 + j*(-103) --128 + j*(23) --92 + j*(30) --112 + j*(88) --8 + j*(170) -122 + j*(83) -81 + j*(-45) --4 + j*(-42) --18 + j*(-16) --43 + j*(-1) --42 + j*(64) -40 + j*(78) -47 + j*(6) --19 + j*(44) -76 + j*(154) -281 + j*(49) -264 + j*(-238) --18 + j*(-369) --266 + j*(-198) --245 + j*(78) --7 + j*(177) -168 + j*(-5) -40 + j*(-248) --272 + j*(-207) --366 + j*(132) --85 + j*(356) -208 + j*(202) -177 + j*(-63) -3 + j*(-96) --23 + j*(-18) --3 + j*(-49) --109 + j*(-69) --184 + j*(77) --69 + j*(223) -105 + j*(208) -198 + j*(93) -202 + j*(-50) -97 + j*(-165) --67 + j*(-153) --146 + j*(-14) --83 + j*(126) -72 + j*(153) -183 + j*(23) -98 + j*(-141) --86 + j*(-95) --59 + j*(91) -134 + j*(71) -122 + j*(-134) --97 + j*(-146) --147 + j*(77) -66 + j*(191) -257 + j*(23) -194 + j*(-226) --39 + j*(-298) --208 + j*(-178) --243 + j*(-25) --216 + j*(119) --76 + j*(247) -144 + j*(186) -151 + j*(-23) -4 + j*(-19) -91 + j*(98) -249 + j*(-80) -41 + j*(-301) --199 + j*(-124) --54 + j*(63) -53 + j*(-95) --144 + j*(-161) --214 + j*(38) --77 + j*(104) --69 + j*(55) --69 + j*(140) -83 + j*(153) -127 + j*(-1) -25 + j*(-45) -27 + j*(0) -44 + j*(-57) --45 + j*(-78) --70 + j*(5) --9 + j*(15) --13 + j*(-43) --80 + j*(-61) --170 + j*(-14) --212 + j*(145) --59 + j*(313) -175 + j*(250) -221 + j*(59) -145 + j*(-12) -130 + j*(-25) -116 + j*(-76) -69 + j*(-121) --23 + j*(-160) --188 + j*(-76) --166 + j*(193) -141 + j*(249) -243 + j*(-24) -41 + j*(-97) -64 + j*(44) -183 + j*(-84) --27 + j*(-175) --50 + j*(114) -363 + j*(58) -303 + j*(-504) --333 + j*(-527) --450 + j*(41) --40 + j*(153) --25 + j*(-122) --240 + j*(-37) --124 + j*(148) --1 + j*(45) --100 + j*(14) --57 + j*(126) -62 + j*(41) --56 + j*(-71) --175 + j*(71) --45 + j*(213) -107 + j*(142) -114 + j*(21) -66 + j*(-37) --12 + j*(-71) --130 + j*(-15) --141 + j*(177) -85 + j*(297) -323 + j*(107) -219 + j*(-204) --95 + j*(-180) --118 + j*(100) -119 + j*(148) -185 + j*(-22) -117 + j*(-76) -129 + j*(-119) -34 + j*(-238) --174 + j*(-164) --153 + j*(57) -23 + j*(79) -60 + j*(-21) -45 + j*(-59) -23 + j*(-130) --110 + j*(-151) --168 + j*(-12) --75 + j*(34) --113 + j*(-22) --182 + j*(123) -25 + j*(248) -192 + j*(50) -38 + j*(-102) --52 + j*(12) -51 + j*(23) -1 + j*(-83) --116 + j*(-6) --47 + j*(104) -17 + j*(71) -16 + j*(99) -153 + j*(109) -215 + j*(-111) --33 + j*(-237) --202 + j*(0) -14 + j*(183) -216 + j*(-10) -61 + j*(-235) --169 + j*(-145) --139 + j*(46) --11 + j*(21) --91 + j*(-76) --228 + j*(60) --99 + j*(269) -136 + j*(210) -139 + j*(28) -42 + j*(33) -100 + j*(93) -185 + j*(6) -139 + j*(-114) -26 + j*(-142) --59 + j*(-71) --20 + j*(39) -111 + j*(11) -86 + j*(-144) --77 + j*(-129) --51 + j*(8) -54 + j*(-62) --78 + j*(-164) --202 + j*(-3) --66 + j*(136) -41 + j*(61) -23 + j*(25) -78 + j*(16) -68 + j*(-111) --93 + j*(-116) --100 + j*(38) -25 + j*(27) --13 + j*(-73) --98 + j*(-31) --88 + j*(21) --105 + j*(69) --13 + j*(190) -216 + j*(78) -108 + j*(-244) --277 + j*(-153) --214 + j*(264) -196 + j*(235) -199 + j*(-131) --99 + j*(-150) --117 + j*(66) -24 + j*(66) --5 + j*(-31) --98 + j*(15) --83 + j*(126) -14 + j*(186) -138 + j*(156) -200 + j*(43) -163 + j*(-57) -107 + j*(-97) -49 + j*(-122) --23 + j*(-93) --13 + j*(-21) -56 + j*(-54) --11 + j*(-151) --169 + j*(-84) --148 + j*(123) -69 + j*(170) -175 + j*(-24) -16 + j*(-158) --123 + j*(-22) -7 + j*(114) -156 + j*(-19) -43 + j*(-183) --119 + j*(-129) --136 + j*(-23) --138 + j*(41) --78 + j*(157) -117 + j*(136) -134 + j*(-84) --78 + j*(-120) --107 + j*(64) -33 + j*(69) --13 + j*(-21) --76 + j*(95) -91 + j*(178) -231 + j*(29) -181 + j*(-138) -58 + j*(-223) --117 + j*(-201) --183 + j*(-8) --10 + j*(71) -25 + j*(-103) --186 + j*(-88) --157 + j*(153) -59 + j*(127) -13 + j*(-8) --35 + j*(103) -158 + j*(102) -157 + j*(-132) --30 + j*(-143) --12 + j*(-71) --68 + j*(-188) --312 + j*(-68) --202 + j*(255) -106 + j*(181) -32 + j*(-31) --72 + j*(78) -74 + j*(97) -14 + j*(-49) --103 + j*(99) -141 + j*(182) -200 + j*(-136) --147 + j*(-175) --165 + j*(148) -81 + j*(121) --36 + j*(-28) --121 + j*(200) -169 + j*(290) -270 + j*(55) -179 + j*(21) -314 + j*(-1) -285 + j*(-309) --81 + j*(-343) --148 + j*(-45) -36 + j*(-34) --51 + j*(-122) --74 + j*(53) -172 + j*(23) -110 + j*(-277) --204 + j*(-220) --161 + j*(42) -7 + j*(-23) --116 + j*(-115) --186 + j*(62) -4 + j*(139) -91 + j*(-23) --27 + j*(-114) --117 + j*(-51) --107 + j*(23) --71 + j*(40) --76 + j*(35) --93 + j*(89) --12 + j*(156) -100 + j*(99) -95 + j*(0) -68 + j*(-22) -71 + j*(-80) --33 + j*(-146) --141 + j*(-59) --110 + j*(25) --114 + j*(23) --142 + j*(128) -8 + j*(211) -113 + j*(82) -28 + j*(33) -90 + j*(103) -182 + j*(-69) --69 + j*(-202) --224 + j*(82) -57 + j*(229) -154 + j*(-28) --82 + j*(-46) --26 + j*(180) -177 + j*(80) -50 + j*(-60) --1 + j*(112) -234 + j*(100) -214 + j*(-171) --30 + j*(-161) --8 + j*(3) -81 + j*(-49) -11 + j*(-83) -39 + j*(-25) -76 + j*(-131) --100 + j*(-167) --144 + j*(49) -84 + j*(95) -136 + j*(-136) --80 + j*(-215) --209 + j*(-57) --156 + j*(109) -3 + j*(178) -167 + j*(73) -132 + j*(-123) --33 + j*(-134) --35 + j*(-33) -21 + j*(-82) --76 + j*(-132) --132 + j*(-34) --72 + j*(-1) --93 + j*(-41) --139 + j*(23) --83 + j*(71) --75 + j*(44) --97 + j*(95) --10 + j*(140) -38 + j*(66) --10 + j*(60) -47 + j*(98) -87 + j*(-15) --70 + j*(-41) --76 + j*(173) -202 + j*(187) -267 + j*(-129) --20 + j*(-264) --206 + j*(-71) --133 + j*(107) --13 + j*(140) -75 + j*(89) -69 + j*(-3) --16 + j*(7) -30 + j*(97) -139 + j*(17) -36 + j*(-110) --91 + j*(18) -63 + j*(139) -184 + j*(-37) -4 + j*(-156) --102 + j*(13) -51 + j*(100) -123 + j*(-25) -40 + j*(-88) --7 + j*(-67) --64 + j*(-44) --83 + j*(100) -135 + j*(192) -322 + j*(-47) -141 + j*(-305) --98 + j*(-221) --71 + j*(-95) --74 + j*(-156) --224 + j*(-89) --173 + j*(126) -46 + j*(119) -59 + j*(-66) --92 + j*(-74) --102 + j*(55) -17 + j*(83) -78 + j*(-22) --5 + j*(-134) --163 + j*(-98) --198 + j*(73) --69 + j*(168) -25 + j*(117) -40 + j*(82) -81 + j*(57) -89 + j*(-18) -42 + j*(-52) -33 + j*(-74) --54 + j*(-149) --226 + j*(-48) --151 + j*(182) -61 + j*(127) --40 + j*(-22) --134 + j*(177) -169 + j*(257) -239 + j*(-114) --183 + j*(-148) --180 + j*(333) -346 + j*(337) -386 + j*(-156) -13 + j*(-190) -69 + j*(57) -272 + j*(-112) -67 + j*(-338) --147 + j*(-214) --138 + j*(-105) --197 + j*(-58) --168 + j*(129) -66 + j*(134) -58 + j*(-88) --147 + j*(-33) --42 + j*(170) -154 + j*(37) -13 + j*(-136) --124 + j*(11) -17 + j*(112) -87 + j*(-14) --11 + j*(-47) --3 + j*(23) -49 + j*(-22) --16 + j*(-62) --42 + j*(8) -30 + j*(13) -21 + j*(-71) --76 + j*(-71) --110 + j*(18) --71 + j*(82) --9 + j*(115) -81 + j*(99) -123 + j*(-4) -43 + j*(-77) --13 + j*(-18) -59 + j*(-4) -41 + j*(-132) --149 + j*(-117) --168 + j*(110) -54 + j*(157) -94 + j*(-24) --43 + j*(-18) -30 + j*(95) -135 + j*(-37) --33 + j*(-132) --107 + j*(57) -92 + j*(104) -111 + j*(-83) --29 + j*(-65) -56 + j*(11) -83 + j*(-171) --190 + j*(-189) --227 + j*(131) -93 + j*(187) -159 + j*(-101) --77 + j*(-175) --156 + j*(-15) --83 + j*(51) --49 + j*(43) --36 + j*(27) --81 + j*(19) --98 + j*(130) -69 + j*(174) -136 + j*(-19) --67 + j*(-74) --95 + j*(139) -124 + j*(143) -112 + j*(-52) --35 + j*(-11) -42 + j*(84) -90 + j*(-14) --3 + j*(-4) -95 + j*(69) -164 + j*(-132) --128 + j*(-231) --281 + j*(105) -27 + j*(307) -236 + j*(92) -127 + j*(-53) -91 + j*(-12) -117 + j*(-66) -21 + j*(-92) -17 + j*(26) -163 + j*(13) -181 + j*(-146) -79 + j*(-215) -19 + j*(-230) --83 + j*(-263) --221 + j*(-168) --188 + j*(5) --35 + j*(-1) --52 + j*(-155) --252 + j*(-163) --347 + j*(56) --194 + j*(232) --23 + j*(169) --54 + j*(60) --143 + j*(129) --72 + j*(266) -100 + j*(289) -249 + j*(188) -310 + j*(-8) -184 + j*(-207) --50 + j*(-197) --107 + j*(-20) -9 + j*(33) -37 + j*(-66) --71 + j*(-104) --163 + j*(-24) --169 + j*(118) --42 + j*(227) -118 + j*(168) -116 + j*(40) -59 + j*(55) -148 + j*(66) -160 + j*(-96) --42 + j*(-122) --75 + j*(100) -170 + j*(142) -241 + j*(-99) -49 + j*(-201) --41 + j*(-86) -25 + j*(-41) -37 + j*(-102) --24 + j*(-126) --75 + j*(-99) --100 + j*(-59) --117 + j*(-15) --122 + j*(64) --17 + j*(167) -188 + j*(89) -176 + j*(-187) --116 + j*(-242) --204 + j*(13) -1 + j*(68) --25 + j*(-117) --233 + j*(-18) --103 + j*(222) -136 + j*(86) --18 + j*(-122) --207 + j*(60) --23 + j*(254) -156 + j*(115) -74 + j*(1) -53 + j*(74) -169 + j*(38) -151 + j*(-116) -9 + j*(-153) --66 + j*(-77) --56 + j*(-2) -1 + j*(18) -27 + j*(-35) --42 + j*(-64) --83 + j*(21) -1 + j*(78) -62 + j*(10) -25 + j*(-33) -25 + j*(-25) -24 + j*(-86) --94 + j*(-115) --179 + j*(21) --87 + j*(153) -40 + j*(136) -84 + j*(81) -120 + j*(39) -149 + j*(-49) -94 + j*(-165) --58 + j*(-222) --250 + j*(-126) --292 + j*(157) --4 + j*(361) -327 + j*(146) -220 + j*(-244) --158 + j*(-236) --211 + j*(86) -41 + j*(154) -88 + j*(-45) --88 + j*(-61) --89 + j*(115) -85 + j*(123) -98 + j*(-33) --39 + j*(-42) --38 + j*(100) -124 + j*(104) -147 + j*(-66) --16 + j*(-96) --28 + j*(74) -194 + j*(75) -242 + j*(-210) --58 + j*(-366) --318 + j*(-151) --255 + j*(142) --24 + j*(223) -139 + j*(105) -119 + j*(-82) --71 + j*(-118) --136 + j*(92) -116 + j*(196) -286 + j*(-92) -3 + j*(-344) --312 + j*(-116) --159 + j*(211) -137 + j*(116) -62 + j*(-134) --164 + j*(-58) --81 + j*(167) -156 + j*(90) -97 + j*(-168) --182 + j*(-148) --221 + j*(134) -23 + j*(240) -168 + j*(72) -91 + j*(-66) --8 + j*(-58) --41 + j*(-9) --33 + j*(50) -40 + j*(79) -105 + j*(7) -54 + j*(-72) --13 + j*(-45) -8 + j*(-11) -19 + j*(-43) --23 + j*(-54) --45 + j*(-25) --45 + j*(-5) --40 + j*(20) --13 + j*(32) --4 + j*(18) -0 + j*(25) -30 + j*(4) --22 + j*(-54) --124 + j*(45) -15 + j*(223) -294 + j*(79) -206 + j*(-286) --193 + j*(-308) --334 + j*(42) --115 + j*(271) -130 + j*(213) -218 + j*(28) -136 + j*(-144) --40 + j*(-163) --117 + j*(-43) --76 + j*(32) --50 + j*(56) -8 + j*(89) -77 + j*(14) --23 + j*(-69) --119 + j*(71) -39 + j*(196) -177 + j*(67) -111 + j*(-15) -162 + j*(22) -255 + j*(-180) --35 + j*(-395) --370 + j*(-116) --168 + j*(276) -217 + j*(171) -198 + j*(-155) --37 + j*(-199) --114 + j*(-66) --65 + j*(12) -12 + j*(21) -74 + j*(-71) --16 + j*(-208) --224 + j*(-183) --316 + j*(28) --198 + j*(214) --19 + j*(222) -58 + j*(128) -44 + j*(74) -54 + j*(69) -66 + j*(15) --12 + j*(-14) --53 + j*(98) -100 + j*(182) -267 + j*(35) -209 + j*(-199) --7 + j*(-283) --209 + j*(-177) --248 + j*(46) --88 + j*(182) -49 + j*(96) --12 + j*(27) --16 + j*(144) -192 + j*(141) -260 + j*(-132) -6 + j*(-308) --255 + j*(-176) --310 + j*(85) --154 + j*(310) -153 + j*(320) -295 + j*(34) -78 + j*(-156) --93 + j*(13) -53 + j*(149) -153 + j*(42) -105 + j*(16) -206 + j*(45) -294 + j*(-177) -48 + j*(-372) --206 + j*(-206) --146 + j*(11) --28 + j*(11) --23 + j*(-14) -11 + j*(-11) -11 + j*(-80) --82 + j*(-71) --68 + j*(40) -57 + j*(23) -50 + j*(-105) --58 + j*(-122) --83 + j*(-64) --75 + j*(-74) --138 + j*(-86) --218 + j*(-9) --206 + j*(144) --28 + j*(240) -173 + j*(89) -70 + j*(-199) --288 + j*(-182) --414 + j*(196) --140 + j*(471) -180 + j*(421) -344 + j*(233) -393 + j*(-2) -255 + j*(-228) -6 + j*(-238) --80 + j*(-84) --32 + j*(-26) --45 + j*(-15) --14 + j*(54) -83 + j*(-1) --13 + j*(-116) --156 + j*(29) -28 + j*(211) -238 + j*(10) -42 + j*(-211) --158 + j*(-20) -36 + j*(136) -151 + j*(-74) --80 + j*(-159) --156 + j*(83) -73 + j*(162) -150 + j*(-23) -24 + j*(-78) -12 + j*(1) -81 + j*(-30) -38 + j*(-105) --42 + j*(-90) --61 + j*(-25) --17 + j*(21) -47 + j*(-12) -19 + j*(-93) --73 + j*(-64) --35 + j*(26) -56 + j*(-37) --26 + j*(-142) --135 + j*(-66) --85 + j*(6) --86 + j*(-47) --186 + j*(16) --110 + j*(165) -38 + j*(110) --9 + j*(1) --79 + j*(61) --27 + j*(107) --32 + j*(104) -21 + j*(213) -260 + j*(155) -242 + j*(-181) --134 + j*(-202) --160 + j*(181) -224 + j*(190) -216 + j*(-189) --139 + j*(-156) --69 + j*(175) -260 + j*(72) -172 + j*(-259) --123 + j*(-233) --154 + j*(-45) --105 + j*(-16) --145 + j*(29) --96 + j*(141) -24 + j*(151) -79 + j*(110) -144 + j*(78) -197 + j*(-41) -103 + j*(-162) --15 + j*(-137) --24 + j*(-78) --23 + j*(-83) --43 + j*(-78) --48 + j*(-87) --113 + j*(-107) --196 + j*(-16) --129 + j*(103) --30 + j*(62) --91 + j*(1) --163 + j*(100) --78 + j*(225) -67 + j*(235) -181 + j*(153) -216 + j*(4) -111 + j*(-110) --6 + j*(-66) -16 + j*(-4) -25 + j*(-49) --65 + j*(-36) --69 + j*(85) -42 + j*(132) -122 + j*(88) -175 + j*(18) -159 + j*(-100) -31 + j*(-126) -30 + j*(-3) -199 + j*(-62) -119 + j*(-332) --223 + j*(-313) --296 + j*(4) --91 + j*(117) --18 + j*(42) -1 + j*(54) -105 + j*(-19) -12 + j*(-202) --216 + j*(-123) --162 + j*(92) --13 + j*(24) --153 + j*(-72) --262 + j*(153) --11 + j*(321) -198 + j*(113) -51 + j*(-77) --103 + j*(44) -4 + j*(185) -151 + j*(115) -144 + j*(-12) -74 + j*(-54) -22 + j*(-39) -2 + j*(20) -88 + j*(78) -228 + j*(-34) -148 + j*(-286) --177 + j*(-305) --310 + j*(6) --71 + j*(195) -112 + j*(17) --47 + j*(-148) --235 + j*(1) --142 + j*(242) -117 + j*(265) -272 + j*(52) -167 + j*(-184) --72 + j*(-199) --171 + j*(-28) --112 + j*(79) --78 + j*(122) -5 + j*(219) -218 + j*(185) -282 + j*(-69) -71 + j*(-206) --76 + j*(-67) -15 + j*(54) -127 + j*(-10) -110 + j*(-136) --12 + j*(-192) --136 + j*(-111) --108 + j*(28) -11 + j*(23) --10 + j*(-81) --129 + j*(-52) --131 + j*(86) --10 + j*(163) -151 + j*(122) -234 + j*(-81) -56 + j*(-294) --225 + j*(-198) --224 + j*(59) --66 + j*(95) --71 + j*(54) --40 + j*(144) -126 + j*(98) -96 + j*(-96) --75 + j*(-85) --69 + j*(23) --50 + j*(-3) --115 + j*(64) -8 + j*(177) -144 + j*(28) --23 + j*(-90) --106 + j*(107) -122 + j*(170) -179 + j*(-56) -0 + j*(-101) -4 + j*(23) -95 + j*(-48) --16 + j*(-141) --111 + j*(-45) --58 + j*(23) --47 + j*(-2) --88 + j*(36) --48 + j*(116) -69 + j*(120) -136 + j*(-18) --23 + j*(-159) --256 + j*(24) --80 + j*(365) -330 + j*(245) -287 + j*(-135) -37 + j*(-103) -168 + j*(-3) -186 + j*(-301) --249 + j*(-327) --316 + j*(146) -108 + j*(220) -131 + j*(-115) --116 + j*(-52) -32 + j*(124) -145 + j*(-91) --105 + j*(-140) --87 + j*(123) -180 + j*(47) -63 + j*(-209) --160 + j*(-81) --38 + j*(88) -64 + j*(-7) -20 + j*(-28) -115 + j*(-38) -99 + j*(-277) --234 + j*(-341) --409 + j*(-42) --264 + j*(163) --161 + j*(181) --78 + j*(243) -97 + j*(187) -78 + j*(-12) --109 + j*(10) --78 + j*(188) -74 + j*(170) -57 + j*(90) -52 + j*(166) -225 + j*(163) -296 + j*(-59) -115 + j*(-217) --72 + j*(-135) --82 + j*(17) --6 + j*(81) -66 + j*(100) -185 + j*(84) -301 + j*(-90) -166 + j*(-356) --186 + j*(-339) --274 + j*(-1) -9 + j*(103) -66 + j*(-180) --290 + j*(-209) --366 + j*(228) -91 + j*(401) -346 + j*(-5) -26 + j*(-292) --251 + j*(-59) --98 + j*(175) -66 + j*(78) --12 + j*(8) --7 + j*(115) -160 + j*(83) -155 + j*(-130) --54 + j*(-180) --153 + j*(-28) --89 + j*(84) --6 + j*(110) -89 + j*(86) -142 + j*(-53) --13 + j*(-197) --251 + j*(-72) --217 + j*(242) -96 + j*(346) -317 + j*(132) -251 + j*(-104) -109 + j*(-132) -105 + j*(-97) -118 + j*(-192) --37 + j*(-279) --204 + j*(-156) --153 + j*(13) --40 + j*(-14) --92 + j*(-90) --186 + j*(-26) --175 + j*(81) --127 + j*(153) --21 + j*(222) -151 + j*(170) -187 + j*(-21) -50 + j*(-118) --42 + j*(-59) --39 + j*(-8) --21 + j*(18) -40 + j*(1) -13 + j*(-132) --224 + j*(-133) --315 + j*(181) --11 + j*(388) -260 + j*(185) -177 + j*(-47) -52 + j*(-30) -74 + j*(-1) -69 + j*(-54) -11 + j*(-70) --47 + j*(-48) --98 + j*(51) -21 + j*(202) -278 + j*(107) -259 + j*(-214) --47 + j*(-292) --184 + j*(-76) --87 + j*(51) --16 + j*(53) -48 + j*(52) -106 + j*(-47) -0 + j*(-146) --110 + j*(-61) --61 + j*(11) --78 + j*(-21) --138 + j*(102) -61 + j*(233) -269 + j*(23) -98 + j*(-221) --117 + j*(-100) --11 + j*(49) -83 + j*(-84) --86 + j*(-168) --194 + j*(12) --35 + j*(151) -134 + j*(22) -34 + j*(-185) --217 + j*(-127) --222 + j*(148) -38 + j*(204) -94 + j*(-13) --94 + j*(-19) --34 + j*(184) -206 + j*(78) -87 + j*(-186) --176 + j*(-74) --70 + j*(165) -139 + j*(65) -45 + j*(-117) --125 + j*(-42) --93 + j*(124) -66 + j*(168) -198 + j*(37) -115 + j*(-163) --119 + j*(-122) --93 + j*(118) -155 + j*(82) -110 + j*(-169) --119 + j*(-132) --86 + j*(26) --31 + j*(-42) --178 + j*(-10) --111 + j*(211) -130 + j*(144) -46 + j*(-66) --131 + j*(70) -38 + j*(249) -221 + j*(107) -157 + j*(-16) -155 + j*(-5) -179 + j*(-116) -18 + j*(-182) --58 + j*(-21) -92 + j*(47) -168 + j*(-78) -130 + j*(-164) -100 + j*(-258) --71 + j*(-373) --326 + j*(-263) --372 + j*(6) --234 + j*(173) --55 + j*(218) -138 + j*(98) -81 + j*(-190) --284 + j*(-191) --366 + j*(220) -19 + j*(387) -223 + j*(95) -37 + j*(-59) --33 + j*(66) -74 + j*(77) -67 + j*(-16) -18 + j*(-8) -35 + j*(-17) --20 + j*(-47) --59 + j*(38) -51 + j*(74) -84 + j*(-63) --71 + j*(-116) --163 + j*(29) --78 + j*(157) -45 + j*(167) -136 + j*(98) -145 + j*(-29) -32 + j*(-86) --31 + j*(0) -45 + j*(35) -37 + j*(-54) --79 + j*(-17) --37 + j*(136) -124 + j*(117) -135 + j*(4) -116 + j*(9) -202 + j*(-54) -114 + j*(-238) --129 + j*(-163) --43 + j*(97) -244 + j*(-28) -110 + j*(-376) --279 + j*(-310) --317 + j*(26) --120 + j*(119) --50 + j*(67) --16 + j*(54) --6 + j*(-23) --122 + j*(-19) --99 + j*(146) -88 + j*(121) -55 + j*(-42) --49 + j*(33) -95 + j*(83) -111 + j*(-130) --130 + j*(-122) --85 + j*(98) -86 + j*(-28) --152 + j*(-158) --274 + j*(185) -112 + j*(320) -233 + j*(-37) --53 + j*(-80) -35 + j*(146) -236 + j*(-71) --59 + j*(-267) --232 + j*(49) -74 + j*(153) -74 + j*(-140) --220 + j*(-44) --60 + j*(252) -216 + j*(71) -47 + j*(-149) --83 + j*(-3) -47 + j*(13) --41 + j*(-135) --235 + j*(13) --110 + j*(233) -67 + j*(183) -64 + j*(119) -117 + j*(146) -194 + j*(61) -143 + j*(-20) -128 + j*(15) -204 + j*(-31) -170 + j*(-153) -68 + j*(-177) -22 + j*(-149) --2 + j*(-132) -5 + j*(-116) --2 + j*(-176) --142 + j*(-200) --238 + j*(-6) --39 + j*(161) -194 + j*(-13) -81 + j*(-310) --246 + j*(-333) --436 + j*(-70) --335 + j*(222) --67 + j*(279) -45 + j*(95) --96 + j*(21) --137 + j*(187) -50 + j*(249) -135 + j*(106) -70 + j*(63) -136 + j*(97) -212 + j*(-73) -5 + j*(-238) --239 + j*(-66) --150 + j*(211) -103 + j*(215) -163 + j*(35) -57 + j*(-25) -30 + j*(62) -146 + j*(84) -233 + j*(-52) -152 + j*(-210) --9 + j*(-251) --136 + j*(-193) --221 + j*(-83) --220 + j*(81) --87 + j*(194) -66 + j*(155) -107 + j*(48) -74 + j*(-18) -21 + j*(-40) --28 + j*(-1) -13 + j*(69) -110 + j*(30) -85 + j*(-83) --18 + j*(-68) -13 + j*(9) -90 + j*(-57) -10 + j*(-161) --117 + j*(-118) --137 + j*(-20) --113 + j*(33) --80 + j*(78) --25 + j*(77) --42 + j*(56) --46 + j*(147) -124 + j*(187) -217 + j*(-13) -31 + j*(-104) -2 + j*(95) -279 + j*(64) -256 + j*(-303) --119 + j*(-344) --187 + j*(-61) --23 + j*(-69) --168 + j*(-178) --296 + j*(68) --33 + j*(220) -90 + j*(-9) --116 + j*(-49) --62 + j*(161) -171 + j*(33) -8 + j*(-227) --273 + j*(-74) --165 + j*(191) -39 + j*(132) -1 + j*(-1) --91 + j*(30) --94 + j*(113) --35 + j*(174) -59 + j*(161) -62 + j*(87) -10 + j*(141) -151 + j*(231) -321 + j*(64) -194 + j*(-141) -42 + j*(-47) -175 + j*(44) -270 + j*(-148) -98 + j*(-295) --53 + j*(-226) --73 + j*(-174) --142 + j*(-168) --224 + j*(-60) --188 + j*(91) --53 + j*(160) -82 + j*(100) -92 + j*(-41) --30 + j*(-74) --54 + j*(42) -82 + j*(57) -119 + j*(-100) --28 + j*(-187) --156 + j*(-103) --156 + j*(23) --69 + j*(81) --1 + j*(32) --45 + j*(-26) --103 + j*(35) --39 + j*(94) --1 + j*(37) --69 + j*(52) --14 + j*(148) -107 + j*(83) -38 + j*(-28) --47 + j*(65) -69 + j*(149) -162 + j*(56) -148 + j*(-6) -187 + j*(-57) -151 + j*(-212) --47 + j*(-245) --120 + j*(-114) --88 + j*(-104) --215 + j*(-94) --254 + j*(150) -25 + j*(280) -215 + j*(49) -75 + j*(-141) --57 + j*(-86) --49 + j*(-52) --116 + j*(-78) --218 + j*(32) --154 + j*(216) -44 + j*(256) -159 + j*(120) -93 + j*(11) -29 + j*(79) -168 + j*(136) -289 + j*(-55) -121 + j*(-248) --80 + j*(-144) --9 + j*(2) -95 + j*(-88) --16 + j*(-204) --158 + j*(-133) --169 + j*(-13) --126 + j*(45) --87 + j*(78) --39 + j*(97) -15 + j*(76) -16 + j*(18) --62 + j*(27) --51 + j*(170) -177 + j*(209) -314 + j*(-57) -86 + j*(-280) --158 + j*(-137) --91 + j*(60) -25 + j*(33) -6 + j*(-6) -29 + j*(25) -83 + j*(-34) -33 + j*(-112) --38 + j*(-119) --115 + j*(-112) --223 + j*(7) --120 + j*(232) -189 + j*(190) -219 + j*(-157) --121 + j*(-256) --274 + j*(45) --37 + j*(234) -153 + j*(59) -25 + j*(-115) --133 + j*(-16) --61 + j*(133) -59 + j*(97) -47 + j*(34) -62 + j*(63) -148 + j*(-17) -33 + j*(-173) --186 + j*(-53) --88 + j*(214) -206 + j*(169) -242 + j*(-101) -56 + j*(-220) --110 + j*(-164) --190 + j*(8) --42 + j*(207) -250 + j*(103) -214 + j*(-243) --114 + j*(-279) --187 + j*(-39) --49 + j*(-1) --78 + j*(-83) --148 + j*(-26) --132 + j*(13) --185 + j*(52) --146 + j*(223) -103 + j*(230) -155 + j*(-30) --83 + j*(-110) --197 + j*(76) --116 + j*(229) -21 + j*(315) -247 + j*(280) -337 + j*(28) -148 + j*(-100) -95 + j*(46) -279 + j*(8) -224 + j*(-229) -4 + j*(-213) -19 + j*(-83) -58 + j*(-142) --37 + j*(-124) -52 + j*(-28) -164 + j*(-220) --91 + j*(-414) --366 + j*(-209) --298 + j*(42) --187 + j*(81) --144 + j*(138) -12 + j*(137) -37 + j*(-57) --192 + j*(-78) --225 + j*(185) -33 + j*(250) -116 + j*(46) --38 + j*(-6) --51 + j*(135) -100 + j*(148) -154 + j*(6) -57 + j*(-79) --26 + j*(-34) --6 + j*(18) -17 + j*(-15) --52 + j*(-29) --91 + j*(77) -27 + j*(167) -163 + j*(81) -145 + j*(-67) -37 + j*(-111) --34 + j*(-67) --49 + j*(-6) --13 + j*(38) -33 + j*(25) -28 + j*(-11) -10 + j*(5) -55 + j*(19) -85 + j*(-62) --13 + j*(-122) --99 + j*(-35) --28 + j*(44) -11 + j*(-31) --107 + j*(-26) --80 + j*(164) -177 + j*(151) -196 + j*(-140) --95 + j*(-177) --123 + j*(104) -161 + j*(116) -181 + j*(-173) --81 + j*(-233) --182 + j*(-49) --103 + j*(49) --45 + j*(55) --7 + j*(40) --18 + j*(9) --38 + j*(62) -76 + j*(97) -147 + j*(-59) -1 + j*(-163) --95 + j*(-69) --64 + j*(-48) --163 + j*(-59) --209 + j*(148) -40 + j*(250) -170 + j*(28) -2 + j*(-81) --56 + j*(37) -15 + j*(49) --16 + j*(30) -20 + j*(98) -111 + j*(29) -21 + j*(-49) --20 + j*(66) -112 + j*(75) -100 + j*(-32) -85 + j*(42) -291 + j*(-49) -173 + j*(-420) --298 + j*(-370) --324 + j*(59) --48 + j*(74) --159 + j*(-41) --181 + j*(245) -249 + j*(251) -287 + j*(-256) --209 + j*(-344) --335 + j*(52) --99 + j*(153) --103 + j*(59) --148 + j*(183) -20 + j*(267) -143 + j*(168) -164 + j*(77) -154 + j*(-22) -39 + j*(-74) --16 + j*(31) -81 + j*(57) -69 + j*(-30) -8 + j*(27) -122 + j*(63) -148 + j*(-88) -8 + j*(-102) -31 + j*(-4) -88 + j*(-91) --49 + j*(-115) --43 + j*(47) -124 + j*(12) -73 + j*(-129) -17 + j*(-69) -127 + j*(-136) --30 + j*(-349) --322 + j*(-190) --207 + j*(65) --92 + j*(-72) --361 + j*(-65) --357 + j*(356) -94 + j*(453) -255 + j*(125) -100 + j*(25) -146 + j*(93) -240 + j*(-49) -127 + j*(-201) --4 + j*(-204) --99 + j*(-184) --204 + j*(-93) --183 + j*(53) --101 + j*(95) --60 + j*(116) -37 + j*(127) -93 + j*(2) --21 + j*(-56) --40 + j*(37) -48 + j*(-22) --98 + j*(-139) --279 + j*(56) --123 + j*(288) -81 + j*(230) -97 + j*(149) -161 + j*(140) -210 + j*(7) -93 + j*(-68) -64 + j*(6) -116 + j*(-44) --8 + j*(-90) --49 + j*(92) -177 + j*(143) -261 + j*(-70) -144 + j*(-159) -139 + j*(-167) -78 + j*(-310) --162 + j*(-307) --234 + j*(-112) --184 + j*(-62) --274 + j*(4) --209 + j*(250) -97 + j*(261) -163 + j*(23) -49 + j*(-13) -113 + j*(1) -88 + j*(-163) --120 + j*(-135) --76 + j*(54) -69 + j*(-40) --93 + j*(-144) --165 + j*(64) -66 + j*(83) -15 + j*(-163) --262 + j*(-41) --98 + j*(272) -240 + j*(97) -84 + j*(-248) --245 + j*(-141) --202 + j*(138) --9 + j*(141) --1 + j*(28) --83 + j*(39) --77 + j*(132) -23 + j*(163) -81 + j*(83) -12 + j*(46) -16 + j*(149) -179 + j*(144) -218 + j*(-46) -69 + j*(-117) -20 + j*(-46) -28 + j*(-66) --68 + j*(-49) --46 + j*(98) -112 + j*(77) -72 + j*(-54) --12 + j*(48) -187 + j*(113) -289 + j*(-169) --6 + j*(-335) --197 + j*(-103) --42 + j*(43) -20 + j*(-68) --81 + j*(-54) --11 + j*(52) -110 + j*(-62) --29 + j*(-222) --240 + j*(-105) --187 + j*(134) -35 + j*(152) -90 + j*(-28) --54 + j*(-78) --71 + j*(60) -93 + j*(36) -40 + j*(-177) --226 + j*(-124) --188 + j*(163) -86 + j*(129) -23 + j*(-124) --231 + j*(-31) --148 + j*(234) -86 + j*(197) -88 + j*(45) -25 + j*(46) -52 + j*(56) -45 + j*(24) -30 + j*(45) -59 + j*(49) -66 + j*(45) -127 + j*(57) -200 + j*(-73) -43 + j*(-219) --136 + j*(-70) -16 + j*(93) -148 + j*(-98) --89 + j*(-221) --221 + j*(32) -6 + j*(159) -101 + j*(-30) --57 + j*(-80) --86 + j*(57) -13 + j*(91) -62 + j*(70) -149 + j*(31) -168 + j*(-148) --50 + j*(-239) --175 + j*(-48) --16 + j*(45) -9 + j*(-124) --214 + j*(-118) --241 + j*(146) --8 + j*(228) -90 + j*(82) -18 + j*(32) -32 + j*(85) -107 + j*(50) -110 + j*(-39) -56 + j*(-98) --40 + j*(-115) --132 + j*(-23) --74 + j*(122) -91 + j*(100) -89 + j*(-47) --24 + j*(-38) -23 + j*(49) -101 + j*(-47) --33 + j*(-129) --115 + j*(35) -75 + j*(115) -168 + j*(-95) --33 + j*(-216) --160 + j*(-74) --98 + j*(11) --95 + j*(-8) --118 + j*(54) --52 + j*(83) --64 + j*(42) --121 + j*(134) -11 + j*(265) -197 + j*(185) -222 + j*(35) -206 + j*(-37) -188 + j*(-154) -32 + j*(-243) --110 + j*(-148) --96 + j*(-51) --106 + j*(-40) --139 + j*(66) -8 + j*(163) -144 + j*(21) -14 + j*(-112) --97 + j*(24) -70 + j*(129) -204 + j*(-57) -37 + j*(-243) --178 + j*(-142) --157 + j*(46) --51 + j*(66) --57 + j*(59) -1 + j*(157) -222 + j*(100) -239 + j*(-216) --88 + j*(-344) --288 + j*(-112) --199 + j*(47) --189 + j*(48) --208 + j*(198) -13 + j*(298) -150 + j*(100) --20 + j*(11) --41 + j*(216) -219 + j*(242) -327 + j*(5) -231 + j*(-164) -106 + j*(-264) --136 + j*(-272) --288 + j*(7) --48 + j*(240) -183 + j*(67) -69 + j*(-98) -8 + j*(-6) -122 + j*(-62) --15 + j*(-235) --255 + j*(-78) --135 + j*(192) -119 + j*(133) -104 + j*(-75) --58 + j*(-89) --105 + j*(45) -6 + j*(143) -162 + j*(75) -156 + j*(-111) --13 + j*(-154) --62 + j*(-30) -33 + j*(-12) -28 + j*(-91) --11 + j*(-88) -13 + j*(-136) --122 + j*(-258) --389 + j*(-124) --364 + j*(233) --42 + j*(342) -110 + j*(139) -2 + j*(38) --25 + j*(129) -90 + j*(124) -81 + j*(5) --28 + j*(35) -36 + j*(149) -177 + j*(70) -100 + j*(-72) --10 + j*(13) -117 + j*(105) -227 + j*(-49) -110 + j*(-186) -2 + j*(-158) --42 + j*(-147) --136 + j*(-84) --80 + j*(61) -59 + j*(-19) --93 + j*(-139) --214 + j*(105) -108 + j*(238) -248 + j*(-132) --146 + j*(-269) --270 + j*(115) -57 + j*(209) -85 + j*(-21) --40 + j*(62) -174 + j*(110) -185 + j*(-214) --194 + j*(-202) --136 + j*(186) -248 + j*(59) -61 + j*(-331) --327 + j*(-134) --161 + j*(205) -70 + j*(64) --84 + j*(-35) --82 + j*(168) -170 + j*(116) -105 + j*(-159) --163 + j*(-94) --102 + j*(147) -100 + j*(89) -31 + j*(-79) --114 + j*(4) --25 + j*(144) -112 + j*(64) -41 + j*(-65) --84 + j*(9) --18 + j*(151) -137 + j*(129) -190 + j*(9) -163 + j*(-89) -85 + j*(-173) --68 + j*(-154) --93 + j*(26) -119 + j*(64) -183 + j*(-209) --139 + j*(-343) --365 + j*(-29) --107 + j*(252) -180 + j*(51) -11 + j*(-232) --279 + j*(-96) --200 + j*(193) -42 + j*(170) -37 + j*(-5) --93 + j*(13) --81 + j*(137) -21 + j*(187) -158 + j*(174) -303 + j*(-10) -155 + j*(-324) --275 + j*(-277) --348 + j*(180) -57 + j*(327) -197 + j*(1) --89 + j*(-71) --107 + j*(244) -254 + j*(283) -382 + j*(-61) -137 + j*(-263) --69 + j*(-141) --19 + j*(32) -138 + j*(8) -135 + j*(-159) --20 + j*(-175) --9 + j*(-51) -126 + j*(-153) --52 + j*(-384) --409 + j*(-234) --389 + j*(165) --78 + j*(276) -81 + j*(133) -94 + j*(11) -42 + j*(-99) --103 + j*(-112) --155 + j*(25) --57 + j*(74) --47 + j*(23) --64 + j*(69) -36 + j*(51) --16 + j*(-105) --230 + j*(-46) --211 + j*(189) --51 + j*(221) --39 + j*(208) -67 + j*(312) -308 + j*(188) -240 + j*(-112) --30 + j*(-91) --16 + j*(126) -153 + j*(117) -170 + j*(12) -156 + j*(-11) -173 + j*(-64) -130 + j*(-112) -123 + j*(-123) -100 + j*(-220) --86 + j*(-247) --170 + j*(-43) -21 + j*(40) -64 + j*(-161) --175 + j*(-176) --196 + j*(100) -91 + j*(138) -151 + j*(-144) --111 + j*(-234) --230 + j*(-19) --85 + j*(96) --11 + j*(9) --78 + j*(-10) --66 + j*(57) --17 + j*(30) --70 + j*(21) --45 + j*(133) -139 + j*(109) -154 + j*(-121) --70 + j*(-189) --165 + j*(-28) --98 + j*(46) --93 + j*(60) --33 + j*(136) -93 + j*(59) --5 + j*(-81) --144 + j*(55) -36 + j*(194) -176 + j*(-16) --49 + j*(-146) --166 + j*(75) -32 + j*(179) -109 + j*(33) -25 + j*(9) -74 + j*(42) -80 + j*(-77) --93 + j*(-79) --105 + j*(128) -111 + j*(162) -170 + j*(-36) --4 + j*(-98) --60 + j*(74) -142 + j*(148) -281 + j*(-80) -70 + j*(-296) --184 + j*(-135) --49 + j*(103) -166 + j*(-62) --46 + j*(-301) --354 + j*(-80) --202 + j*(281) -147 + j*(244) -206 + j*(-15) -78 + j*(-109) -20 + j*(-95) --17 + j*(-116) --112 + j*(-98) --159 + j*(30) --44 + j*(146) -110 + j*(66) -59 + j*(-88) --69 + j*(-35) -13 + j*(67) -104 + j*(-51) --37 + j*(-129) --83 + j*(6) -40 + j*(-13) --67 + j*(-129) --181 + j*(74) -120 + j*(185) -238 + j*(-213) --223 + j*(-363) --411 + j*(107) --2 + j*(288) -109 + j*(-43) --169 + j*(-46) --73 + j*(214) -182 + j*(56) --7 + j*(-186) --223 + j*(5) --57 + j*(177) -38 + j*(27) --137 + j*(19) --122 + j*(259) -152 + j*(303) -272 + j*(86) --58 + j*(-93) --100 + j*(0) --47 + j*(62) --12 + j*(48) --19 + j*(68) -38 + j*(112) -134 + j*(77) -177 + j*(-38) -98 + j*(-164) --70 + j*(-146) --91 + j*(26) -86 + j*(44) -100 + j*(-155) --105 + j*(-187) --153 + j*(-31) --88 + j*(-11) --148 + j*(4) --104 + j*(144) -77 + j*(93) -1 + j*(-83) --163 + j*(29) --42 + j*(179) -59 + j*(88) -6 + j*(103) -173 + j*(161) -295 + j*(-125) --27 + j*(-320) --240 + j*(-48) --51 + j*(89) --64 + j*(-56) --240 + j*(108) --5 + j*(366) -302 + j*(178) -229 + j*(-81) -117 + j*(-100) -71 + j*(-159) --107 + j*(-115) --44 + j*(127) -263 + j*(4) -87 + j*(-390) --380 + j*(-223) --282 + j*(247) -94 + j*(209) -51 + j*(-11) --28 + j*(110) -204 + j*(122) -228 + j*(-181) --72 + j*(-256) --180 + j*(-27) --45 + j*(78) -35 + j*(24) -47 + j*(-24) -25 + j*(-95) --91 + j*(-107) --139 + j*(34) -9 + j*(113) -112 + j*(-32) --18 + j*(-163) --177 + j*(-57) --107 + j*(117) -78 + j*(79) -77 + j*(-130) --155 + j*(-194) --317 + j*(21) --192 + j*(254) -25 + j*(245) -75 + j*(124) -42 + j*(116) -113 + j*(134) -172 + j*(31) -92 + j*(-42) -69 + j*(21) -177 + j*(-21) -120 + j*(-209) --117 + j*(-191) --136 + j*(36) -48 + j*(42) -5 + j*(-117) --158 + j*(-22) --24 + j*(159) -185 + j*(-5) -11 + j*(-269) --325 + j*(-140) --317 + j*(235) --3 + j*(373) -219 + j*(210) -212 + j*(26) -151 + j*(-43) -105 + j*(-101) --23 + j*(-127) --122 + j*(30) -38 + j*(196) -255 + j*(71) -202 + j*(-150) -57 + j*(-155) -62 + j*(-115) -39 + j*(-182) --60 + j*(-165) --47 + j*(-109) --64 + j*(-175) --222 + j*(-132) --204 + j*(82) -8 + j*(83) -1 + j*(-105) --180 + j*(-86) --175 + j*(76) --64 + j*(91) --54 + j*(36) --90 + j*(42) --106 + j*(91) --60 + j*(166) -63 + j*(159) -100 + j*(40) -21 + j*(1) -16 + j*(33) -9 + j*(-4) --69 + j*(47) -34 + j*(168) -188 + j*(21) -13 + j*(-138) --121 + j*(76) -148 + j*(175) -223 + j*(-135) --93 + j*(-193) --115 + j*(88) -107 + j*(58) -14 + j*(-93) --54 + j*(69) -182 + j*(64) -148 + j*(-245) --184 + j*(-229) --210 + j*(34) --93 + j*(59) --148 + j*(106) --1 + j*(295) -303 + j*(149) -215 + j*(-178) --49 + j*(-133) -8 + j*(54) -163 + j*(-39) -81 + j*(-192) --59 + j*(-179) --118 + j*(-100) --118 + j*(-17) --53 + j*(13) --23 + j*(-49) --103 + j*(-74) --150 + j*(24) --73 + j*(118) -40 + j*(91) -52 + j*(-34) --111 + j*(-65) --180 + j*(177) -151 + j*(338) -451 + j*(-25) -139 + j*(-444) --315 + j*(-242) --226 + j*(152) -42 + j*(132) -35 + j*(14) -57 + j*(62) -177 + j*(-66) --3 + j*(-282) --297 + j*(-113) --188 + j*(219) -132 + j*(180) -148 + j*(-101) --95 + j*(-163) --209 + j*(33) --90 + j*(197) -86 + j*(182) -173 + j*(62) -156 + j*(-76) -34 + j*(-168) --134 + j*(-119) --182 + j*(73) --31 + j*(220) -190 + j*(178) -297 + j*(-51) -141 + j*(-304) --197 + j*(-269) --278 + j*(76) -25 + j*(207) -144 + j*(-59) --113 + j*(-132) --148 + j*(136) -122 + j*(145) -107 + j*(-110) --127 + j*(-78) --93 + j*(135) -77 + j*(127) -96 + j*(30) -80 + j*(14) -95 + j*(-9) -99 + j*(-38) -117 + j*(-107) -3 + j*(-215) --190 + j*(-97) --77 + j*(134) -146 + j*(0) --30 + j*(-206) --221 + j*(6) -1 + j*(166) -99 + j*(-44) --90 + j*(-54) --4 + j*(112) -129 + j*(-68) --141 + j*(-153) --177 + j*(202) -255 + j*(204) -247 + j*(-276) --231 + j*(-282) --257 + j*(129) -39 + j*(151) -18 + j*(-12) --31 + j*(76) -124 + j*(52) -65 + j*(-145) --137 + j*(-75) --69 + j*(94) -24 + j*(14) --105 + j*(13) --45 + j*(247) -314 + j*(206) -386 + j*(-235) --34 + j*(-457) --368 + j*(-156) --218 + j*(197) -83 + j*(174) -133 + j*(-45) -3 + j*(-134) --103 + j*(-102) --164 + j*(-21) --149 + j*(93) --49 + j*(140) -1 + j*(98) --2 + j*(107) -66 + j*(122) -112 + j*(45) -75 + j*(13) -108 + j*(7) -89 + j*(-122) --135 + j*(-112) --146 + j*(194) -220 + j*(252) -347 + j*(-121) -47 + j*(-301) --122 + j*(-133) --78 + j*(-59) --132 + j*(-39) --121 + j*(107) -43 + j*(123) -65 + j*(3) -0 + j*(6) -28 + j*(19) --25 + j*(-3) --30 + j*(155) -253 + j*(176) -336 + j*(-194) --51 + j*(-327) --173 + j*(32) -180 + j*(102) -216 + j*(-272) --151 + j*(-323) --221 + j*(-20) -2 + j*(30) -21 + j*(-152) --139 + j*(-194) --252 + j*(-92) --257 + j*(56) --141 + j*(144) --59 + j*(66) --171 + j*(40) --189 + j*(245) -78 + j*(329) -228 + j*(83) -52 + j*(-64) --35 + j*(65) -88 + j*(93) -81 + j*(-29) --19 + j*(4) -51 + j*(73) -91 + j*(-49) --89 + j*(-61) --86 + j*(194) -256 + j*(208) -338 + j*(-194) --61 + j*(-372) --310 + j*(-57) --134 + j*(196) -39 + j*(155) -78 + j*(124) -184 + j*(71) -158 + j*(-110) --35 + j*(-86) -41 + j*(105) -264 + j*(-45) -71 + j*(-322) --231 + j*(-133) --52 + j*(143) -177 + j*(-59) --62 + j*(-261) --265 + j*(-12) --57 + j*(189) -100 + j*(47) -11 + j*(-28) -30 + j*(59) -171 + j*(-17) -115 + j*(-232) --136 + j*(-275) --298 + j*(-68) --198 + j*(163) -26 + j*(162) -63 + j*(-18) --88 + j*(-41) --87 + j*(114) -82 + j*(100) -62 + j*(-83) --148 + j*(-65) --165 + j*(178) -78 + j*(281) -283 + j*(105) -230 + j*(-146) -14 + j*(-204) --83 + j*(-59) -19 + j*(8) -47 + j*(-107) --103 + j*(-122) --119 + j*(39) -34 + j*(43) -8 + j*(-108) --144 + j*(-64) --92 + j*(64) --23 + j*(-25) --202 + j*(-58) --268 + j*(207) --1 + j*(356) -174 + j*(184) -100 + j*(89) -133 + j*(158) -271 + j*(72) -241 + j*(-103) -148 + j*(-155) -100 + j*(-218) --76 + j*(-274) --255 + j*(-100) --162 + j*(118) --14 + j*(100) --36 + j*(74) -29 + j*(173) -219 + j*(96) -190 + j*(-135) --16 + j*(-155) --52 + j*(0) -69 + j*(35) -124 + j*(-68) -57 + j*(-160) --52 + j*(-144) --59 + j*(-53) -17 + j*(-84) --78 + j*(-204) --276 + j*(-84) --190 + j*(167) -47 + j*(124) -13 + j*(-64) --138 + j*(-23) --124 + j*(95) --76 + j*(151) -35 + j*(229) -257 + j*(121) -202 + j*(-192) --126 + j*(-186) --129 + j*(104) -112 + j*(78) -50 + j*(-122) --115 + j*(-42) --47 + j*(78) -13 + j*(50) -39 + j*(70) -154 + j*(0) -69 + j*(-195) --146 + j*(-127) --76 + j*(21) --59 + j*(-121) --358 + j*(-37) --269 + j*(436) -284 + j*(436) -382 + j*(-49) -68 + j*(-164) -28 + j*(-40) -11 + j*(-114) --161 + j*(-1) -25 + j*(226) -277 + j*(-13) -2 + j*(-267) --229 + j*(18) -38 + j*(206) -164 + j*(-23) --12 + j*(-69) -23 + j*(59) -113 + j*(-27) -19 + j*(-70) -52 + j*(20) -153 + j*(-98) -1 + j*(-229) --131 + j*(-111) --78 + j*(-48) --129 + j*(-68) --166 + j*(77) -5 + j*(139) -53 + j*(0) --34 + j*(21) -91 + j*(74) -140 + j*(-159) --173 + j*(-236) --292 + j*(107) -22 + j*(258) -171 + j*(2) --24 + j*(-113) --100 + j*(34) -14 + j*(82) -34 + j*(-3) --37 + j*(-2) --23 + j*(80) -86 + j*(86) -136 + j*(-40) -23 + j*(-136) --95 + j*(-59) --56 + j*(43) -0 + j*(30) --11 + j*(40) -77 + j*(76) -170 + j*(-75) -3 + j*(-244) --219 + j*(-118) --163 + j*(91) --27 + j*(72) --74 + j*(15) --110 + j*(128) -45 + j*(200) -165 + j*(61) -72 + j*(-80) --64 + j*(-24) --37 + j*(105) -81 + j*(119) -138 + j*(49) -156 + j*(-16) -142 + j*(-117) -9 + j*(-184) --108 + j*(-65) --1 + j*(55) -105 + j*(-69) --52 + j*(-182) --187 + j*(-1) --2 + j*(153) -178 + j*(-25) -27 + j*(-255) --250 + j*(-187) --313 + j*(76) --156 + j*(240) --13 + j*(222) -21 + j*(215) -143 + j*(276) -366 + j*(147) -343 + j*(-151) -117 + j*(-214) -105 + j*(-119) -141 + j*(-264) --132 + j*(-344) --269 + j*(-49) --8 + j*(69) -23 + j*(-182) --247 + j*(-142) --164 + j*(129) -55 + j*(-15) --192 + j*(-189) --375 + j*(148) --27 + j*(369) -183 + j*(85) --32 + j*(-37) --41 + j*(161) -185 + j*(100) -115 + j*(-148) --120 + j*(-119) --140 + j*(70) --25 + j*(124) -41 + j*(73) -18 + j*(6) --73 + j*(35) --45 + j*(182) -153 + j*(185) -195 + j*(-16) -21 + j*(-59) -9 + j*(117) -218 + j*(127) -294 + j*(-98) -137 + j*(-260) --60 + j*(-227) --136 + j*(-63) --22 + j*(70) -148 + j*(-11) -111 + j*(-217) --107 + j*(-260) --231 + j*(-105) --192 + j*(38) --115 + j*(89) --54 + j*(93) --22 + j*(81) -1 + j*(84) -52 + j*(76) -77 + j*(13) -37 + j*(-25) -25 + j*(8) -88 + j*(-7) -87 + j*(-119) --45 + j*(-185) --189 + j*(-96) --198 + j*(83) --51 + j*(183) -87 + j*(113) -77 + j*(4) -25 + j*(16) -90 + j*(40) -155 + j*(-81) -42 + j*(-221) --137 + j*(-199) --225 + j*(-76) --243 + j*(45) --204 + j*(182) --61 + j*(288) -133 + j*(248) -224 + j*(81) -153 + j*(-76) -4 + j*(-97) --74 + j*(21) -14 + j*(138) -168 + j*(95) -193 + j*(-69) -64 + j*(-153) --27 + j*(-81) -20 + j*(-16) -66 + j*(-81) --18 + j*(-142) --101 + j*(-75) --67 + j*(-4) --41 + j*(-32) --103 + j*(-24) --98 + j*(81) -29 + j*(103) -74 + j*(-22) --47 + j*(-78) --127 + j*(41) --26 + j*(160) -125 + j*(113) -160 + j*(-31) -75 + j*(-139) --60 + j*(-154) --174 + j*(-51) --153 + j*(119) -6 + j*(189) -113 + j*(96) -94 + j*(30) -121 + j*(30) -172 + j*(-88) -10 + j*(-219) --187 + j*(-54) --39 + j*(184) -237 + j*(52) -151 + j*(-251) --156 + j*(-244) --231 + j*(13) --58 + j*(145) -87 + j*(50) -42 + j*(-88) --91 + j*(-62) --61 + j*(79) -98 + j*(30) -33 + j*(-157) --182 + j*(-86) --115 + j*(130) -73 + j*(50) --46 + j*(-101) --185 + j*(64) -5 + j*(214) -159 + j*(35) -18 + j*(-108) --103 + j*(-11) --60 + j*(83) --4 + j*(95) -47 + j*(91) -85 + j*(33) -40 + j*(-16) -4 + j*(17) -15 + j*(41) -26 + j*(81) -150 + j*(123) -303 + j*(-62) -138 + j*(-344) --212 + j*(-277) --256 + j*(30) --73 + j*(128) --6 + j*(70) -5 + j*(75) -61 + j*(65) -85 + j*(18) -101 + j*(-24) -77 + j*(-115) --62 + j*(-132) --110 + j*(13) -10 + j*(68) -47 + j*(-10) -30 + j*(-11) -99 + j*(-71) --31 + j*(-247) --332 + j*(-99) --231 + j*(294) -177 + j*(280) -240 + j*(-62) -8 + j*(-164) --102 + j*(-46) --88 + j*(66) -23 + j*(156) -206 + j*(66) -171 + j*(-167) --32 + j*(-187) --60 + j*(-83) --61 + j*(-118) --185 + j*(-63) --129 + j*(107) -15 + j*(49) --84 + j*(-28) --100 + j*(136) -112 + j*(112) -54 + j*(-110) --141 + j*(-11) -1 + j*(137) -76 + j*(-54) --173 + j*(-47) --104 + j*(264) -245 + j*(156) -110 + j*(-190) --223 + j*(-24) --37 + j*(310) -304 + j*(158) -242 + j*(-159) --3 + j*(-188) --87 + j*(-29) -23 + j*(78) -160 + j*(-24) -63 + j*(-215) --173 + j*(-147) --156 + j*(84) -15 + j*(103) -30 + j*(21) -25 + j*(35) -62 + j*(-1) -10 + j*(-11) -81 + j*(68) -237 + j*(-103) -16 + j*(-366) --320 + j*(-170) --194 + j*(140) -1 + j*(51) --114 + j*(-6) --73 + j*(151) -81 + j*(52) --91 + j*(-49) --141 + j*(226) -212 + j*(274) -280 + j*(-65) -42 + j*(-98) -131 + j*(21) -194 + j*(-222) --152 + j*(-291) --223 + j*(76) -125 + j*(115) -122 + j*(-217) --176 + j*(-213) --190 + j*(-3) --119 + j*(-14) --219 + j*(14) --203 + j*(210) --6 + j*(287) -149 + j*(202) -209 + j*(55) -133 + j*(-83) -2 + j*(-46) -74 + j*(49) -179 + j*(-95) -3 + j*(-258) --199 + j*(-132) --170 + j*(35) --119 + j*(71) --83 + j*(136) -38 + j*(141) -54 + j*(34) --25 + j*(61) -61 + j*(153) -182 + j*(53) -131 + j*(-63) -85 + j*(-67) -73 + j*(-127) --61 + j*(-151) --122 + j*(-9) --18 + j*(52) -4 + j*(-5) --14 + j*(23) -58 + j*(1) --18 + j*(-116) --194 + j*(16) --37 + j*(268) -283 + j*(143) -243 + j*(-203) --57 + j*(-267) --205 + j*(-64) --112 + j*(121) -74 + j*(116) -119 + j*(-62) --58 + j*(-122) --123 + j*(66) -80 + j*(141) -176 + j*(-57) -19 + j*(-171) --87 + j*(-83) --71 + j*(-20) --68 + j*(3) --41 + j*(40) --4 + j*(32) --2 + j*(34) -58 + j*(47) -114 + j*(-51) -21 + j*(-151) --78 + j*(-112) --97 + j*(-73) --161 + j*(-37) --148 + j*(109) -38 + j*(129) -73 + j*(-78) --150 + j*(-136) --269 + j*(67) --170 + j*(247) --1 + j*(320) -208 + j*(259) -281 + j*(28) -121 + j*(-89) -81 + j*(-4) -174 + j*(-98) --25 + j*(-274) --297 + j*(-57) --144 + j*(271) -159 + j*(225) -216 + j*(40) -196 + j*(-65) -116 + j*(-190) --76 + j*(-161) --54 + j*(21) -95 + j*(-53) --59 + j*(-198) --228 + j*(7) --27 + j*(187) -124 + j*(35) -44 + j*(-49) -60 + j*(-37) -15 + j*(-174) --230 + j*(-104) --174 + j*(205) -130 + j*(169) -79 + j*(-66) --72 + j*(47) -117 + j*(155) -221 + j*(-62) -61 + j*(-147) -62 + j*(-91) -47 + j*(-239) --243 + j*(-231) --281 + j*(124) -54 + j*(195) -121 + j*(-86) --101 + j*(-129) --133 + j*(22) --74 + j*(42) --87 + j*(78) -10 + j*(142) -106 + j*(36) -32 + j*(-50) -4 + j*(-21) --4 + j*(-89) --188 + j*(-73) --204 + j*(218) -144 + j*(295) -277 + j*(-48) --11 + j*(-194) --123 + j*(30) -61 + j*(74) -34 + j*(-107) --177 + j*(-31) --98 + j*(231) -204 + j*(197) -244 + j*(-111) --33 + j*(-225) --197 + j*(-1) --30 + j*(187) -153 + j*(67) -63 + j*(-95) --81 + j*(-9) -12 + j*(141) -190 + j*(67) -177 + j*(-129) -13 + j*(-197) --107 + j*(-113) --117 + j*(-1) --60 + j*(71) -23 + j*(88) -100 + j*(35) -88 + j*(-69) --11 + j*(-82) --11 + j*(6) -96 + j*(-40) -5 + j*(-206) --248 + j*(-99) --163 + j*(227) -199 + j*(185) -191 + j*(-167) --119 + j*(-162) --76 + j*(105) -180 + j*(8) -55 + j*(-266) --228 + j*(-161) --160 + j*(80) -11 + j*(8) --114 + j*(-124) --274 + j*(42) --139 + j*(257) -96 + j*(208) -119 + j*(18) --11 + j*(-27) --40 + j*(74) -57 + j*(83) -52 + j*(-25) --79 + j*(-2) --48 + j*(165) -156 + j*(155) -175 + j*(-50) --1 + j*(-70) -21 + j*(83) -192 + j*(18) -117 + j*(-190) --97 + j*(-135) --58 + j*(47) -81 + j*(-12) --18 + j*(-130) --134 + j*(4) -12 + j*(124) -128 + j*(-17) -5 + j*(-112) --49 + j*(-5) -57 + j*(1) -31 + j*(-127) --113 + j*(-108) --129 + j*(9) --81 + j*(48) --56 + j*(81) -28 + j*(83) -38 + j*(-24) --100 + j*(-11) --66 + j*(181) -176 + j*(162) -204 + j*(-91) -9 + j*(-158) --65 + j*(-59) --69 + j*(-22) --90 + j*(67) -57 + j*(156) -198 + j*(-14) -37 + j*(-180) --115 + j*(-44) -4 + j*(60) -52 + j*(-54) --56 + j*(-61) --39 + j*(26) --1 + j*(-2) --39 + j*(29) -76 + j*(92) -187 + j*(-96) --28 + j*(-264) --224 + j*(-92) --122 + j*(61) --80 + j*(-1) --158 + j*(60) --59 + j*(183) -66 + j*(103) -13 + j*(32) -11 + j*(85) -72 + j*(45) -11 + j*(-5) --17 + j*(65) -42 + j*(86) -44 + j*(95) -161 + j*(163) -363 + j*(-30) -178 + j*(-357) --187 + j*(-235) --96 + j*(74) -130 + j*(-52) --52 + j*(-229) --209 + j*(-28) --30 + j*(89) -23 + j*(-59) --107 + j*(-59) --92 + j*(40) --68 + j*(20) --115 + j*(91) -22 + j*(194) -168 + j*(57) -70 + j*(-71) -26 + j*(-2) -120 + j*(-66) --8 + j*(-235) --249 + j*(-124) --223 + j*(129) --40 + j*(185) -47 + j*(116) -68 + j*(49) -35 + j*(-7) --30 + j*(8) --28 + j*(79) -33 + j*(113) -123 + j*(102) -204 + j*(-24) -76 + j*(-203) --170 + j*(-90) --69 + j*(195) -245 + j*(95) -158 + j*(-240) --174 + j*(-190) --177 + j*(107) -42 + j*(163) -142 + j*(49) -151 + j*(-68) -50 + j*(-195) --172 + j*(-136) --173 + j*(142) -119 + j*(221) -278 + j*(-36) -114 + j*(-250) --102 + j*(-200) --130 + j*(-32) --1 + j*(11) -24 + j*(-122) --148 + j*(-151) --196 + j*(33) --47 + j*(76) --72 + j*(-30) --170 + j*(101) -50 + j*(231) -221 + j*(-35) --45 + j*(-224) --215 + j*(4) --42 + j*(105) --57 + j*(-28) --194 + j*(96) --16 + j*(271) -156 + j*(112) -44 + j*(19) -76 + j*(128) -238 + j*(-6) -78 + j*(-228) --148 + j*(-119) --98 + j*(23) --104 + j*(-27) --246 + j*(102) --106 + j*(381) -239 + j*(347) -337 + j*(71) -212 + j*(-62) -150 + j*(-42) -183 + j*(-61) -163 + j*(-170) -12 + j*(-219) --98 + j*(-71) -46 + j*(55) -183 + j*(-117) --18 + j*(-289) --238 + j*(-91) --73 + j*(152) -176 + j*(39) -127 + j*(-198) --57 + j*(-233) --146 + j*(-152) --180 + j*(-85) --200 + j*(1) --144 + j*(107) -1 + j*(119) -73 + j*(-41) --114 + j*(-161) --310 + j*(48) --119 + j*(334) -217 + j*(216) -178 + j*(-86) --22 + j*(-79) -32 + j*(16) -74 + j*(-133) --153 + j*(-197) --279 + j*(30) --129 + j*(180) --37 + j*(119) --78 + j*(130) --8 + j*(230) -156 + j*(186) -185 + j*(20) -64 + j*(-52) -2 + j*(38) -104 + j*(86) -163 + j*(-53) -3 + j*(-146) --120 + j*(19) -37 + j*(163) -194 + j*(24) -87 + j*(-128) --36 + j*(-46) -44 + j*(45) -132 + j*(-40) -68 + j*(-155) --65 + j*(-154) --138 + j*(-47) --95 + j*(70) -10 + j*(97) -74 + j*(43) -95 + j*(-16) -81 + j*(-103) --44 + j*(-167) --199 + j*(-45) --132 + j*(197) -158 + j*(233) -322 + j*(-40) -137 + j*(-305) --164 + j*(-239) --192 + j*(28) -18 + j*(87) -59 + j*(-82) --100 + j*(-79) --55 + j*(91) -147 + j*(14) -74 + j*(-220) --156 + j*(-181) --140 + j*(-11) --47 + j*(-61) --153 + j*(-135) --257 + j*(-30) --238 + j*(66) --244 + j*(126) --209 + j*(260) --46 + j*(312) -22 + j*(236) -9 + j*(281) -201 + j*(363) -430 + j*(145) -317 + j*(-176) -32 + j*(-187) --30 + j*(-4) -60 + j*(49) -90 + j*(29) -136 + j*(47) -245 + j*(-40) -196 + j*(-244) --38 + j*(-298) --174 + j*(-123) --88 + j*(11) --17 + j*(-28) --68 + j*(-49) --83 + j*(29) --5 + j*(65) -43 + j*(22) -53 + j*(-15) -59 + j*(-69) --15 + j*(-142) --151 + j*(-98) --187 + j*(67) --66 + j*(193) -110 + j*(187) -238 + j*(45) -207 + j*(-169) -2 + j*(-263) --160 + j*(-136) --109 + j*(12) --6 + j*(-22) --65 + j*(-117) --212 + j*(-54) --209 + j*(144) --12 + j*(242) -166 + j*(105) -113 + j*(-104) --93 + j*(-127) --184 + j*(53) --57 + j*(207) -129 + j*(167) -175 + j*(4) -84 + j*(-77) -45 + j*(-45) -97 + j*(-89) -6 + j*(-246) --279 + j*(-209) --381 + j*(130) --100 + j*(376) -206 + j*(229) -187 + j*(-40) --4 + j*(-87) --64 + j*(35) -8 + j*(90) -42 + j*(54) -29 + j*(59) -69 + j*(88) -132 + j*(49) -135 + j*(-20) -111 + j*(-54) -91 + j*(-91) -34 + j*(-111) --1 + j*(-77) -13 + j*(-76) --38 + j*(-104) --95 + j*(-18) -4 + j*(59) -75 + j*(-46) --35 + j*(-94) --40 + j*(23) -91 + j*(-29) --1 + j*(-185) --167 + j*(-86) --81 + j*(33) --61 + j*(-68) --223 + j*(7) --105 + j*(243) -148 + j*(127) -32 + j*(-69) --72 + j*(95) -171 + j*(127) -173 + j*(-175) --131 + j*(-167) --89 + j*(83) -95 + j*(-29) --90 + j*(-171) --210 + j*(43) --22 + j*(119) --40 + j*(-27) --184 + j*(100) -2 + j*(282) -200 + j*(127) -130 + j*(-17) -111 + j*(-9) -117 + j*(-129) --94 + j*(-177) --190 + j*(54) -12 + j*(165) -109 + j*(14) -8 + j*(-57) --64 + j*(-12) --117 + j*(70) --55 + j*(274) -291 + j*(320) -506 + j*(-68) -216 + j*(-407) --111 + j*(-269) --52 + j*(-72) -22 + j*(-175) --177 + j*(-229) --292 + j*(14) --74 + j*(188) -116 + j*(2) --67 + j*(-202) --332 + j*(-25) --221 + j*(295) -78 + j*(299) -143 + j*(116) -87 + j*(101) -180 + j*(128) -279 + j*(-5) -235 + j*(-170) -111 + j*(-284) --101 + j*(-310) --286 + j*(-110) --165 + j*(149) -86 + j*(95) -54 + j*(-112) --113 + j*(-77) --71 + j*(54) -33 + j*(-2) --43 + j*(-102) --169 + j*(-28) --141 + j*(131) -21 + j*(176) -119 + j*(57) -62 + j*(-42) -23 + j*(-21) -62 + j*(-74) --66 + j*(-185) --256 + j*(-33) --129 + j*(194) -70 + j*(87) --54 + j*(-48) --144 + j*(112) -21 + j*(165) -12 + j*(29) --115 + j*(135) -61 + j*(291) -226 + j*(127) -120 + j*(44) -197 + j*(144) -371 + j*(-76) -93 + j*(-339) --199 + j*(-67) -62 + j*(204) -298 + j*(-40) -105 + j*(-233) --4 + j*(-117) -64 + j*(-120) --18 + j*(-175) --41 + j*(-80) -53 + j*(-147) --121 + j*(-286) --337 + j*(-67) --146 + j*(177) -47 + j*(35) --89 + j*(-62) --99 + j*(100) -95 + j*(51) -17 + j*(-166) --212 + j*(-88) --161 + j*(119) --18 + j*(93) --62 + j*(25) --94 + j*(119) -40 + j*(178) -163 + j*(55) -100 + j*(-137) --139 + j*(-170) --284 + j*(79) --76 + j*(322) -199 + j*(191) -124 + j*(-40) --28 + j*(47) -128 + j*(159) -260 + j*(-51) -57 + j*(-220) --107 + j*(-76) --18 + j*(35) -21 + j*(-42) --72 + j*(-40) --78 + j*(76) -26 + j*(135) -158 + j*(83) -202 + j*(-102) -0 + j*(-253) --227 + j*(-74) --90 + j*(181) -142 + j*(74) -46 + j*(-95) --36 + j*(17) -120 + j*(2) -25 + j*(-218) --256 + j*(-74) --93 + j*(234) -197 + j*(65) -5 + j*(-176) --179 + j*(49) -68 + j*(189) -176 + j*(-54) --35 + j*(-127) --68 + j*(35) -38 + j*(34) -17 + j*(-4) -62 + j*(30) -120 + j*(-97) --59 + j*(-191) --181 + j*(-20) --69 + j*(86) --48 + j*(62) --11 + j*(187) -285 + j*(157) -341 + j*(-256) --76 + j*(-428) --305 + j*(-126) --152 + j*(51) --106 + j*(-14) --175 + j*(42) --112 + j*(139) --47 + j*(139) --3 + j*(173) -124 + j*(151) -150 + j*(21) -98 + j*(-5) -159 + j*(-37) -103 + j*(-225) --169 + j*(-203) --190 + j*(72) -42 + j*(92) -26 + j*(-97) --136 + j*(-57) --112 + j*(64) --71 + j*(72) --46 + j*(134) -115 + j*(112) -98 + j*(-119) --182 + j*(-112) --197 + j*(175) -30 + j*(197) --2 + j*(75) --61 + j*(226) -189 + j*(305) -315 + j*(74) -192 + j*(-13) -255 + j*(34) -334 + j*(-185) -63 + j*(-341) --110 + j*(-105) -100 + j*(14) -175 + j*(-221) --57 + j*(-315) --185 + j*(-172) --187 + j*(-81) --210 + j*(38) --52 + j*(190) -195 + j*(50) -103 + j*(-244) --187 + j*(-214) --216 + j*(17) --74 + j*(57) --68 + j*(-6) --95 + j*(25) --50 + j*(40) --60 + j*(-6) --115 + j*(25) --94 + j*(90) --54 + j*(87) --71 + j*(102) --31 + j*(175) -88 + j*(174) -153 + j*(68) -116 + j*(-25) -47 + j*(-53) --10 + j*(-28) --8 + j*(33) -66 + j*(31) -66 + j*(-81) --95 + j*(-101) --158 + j*(102) -57 + j*(216) -211 + j*(13) -25 + j*(-153) --134 + j*(28) -48 + j*(187) -210 + j*(25) -92 + j*(-111) -34 + j*(-24) -149 + j*(-68) -56 + j*(-260) --198 + j*(-196) --202 + j*(29) --91 + j*(60) --122 + j*(81) --25 + j*(231) -221 + j*(131) -146 + j*(-146) --112 + j*(-62) -26 + j*(181) -291 + j*(2) -134 + j*(-296) --140 + j*(-214) --124 + j*(-47) --105 + j*(-64) --187 + j*(31) --49 + j*(195) -172 + j*(66) -89 + j*(-181) --160 + j*(-173) --251 + j*(30) --158 + j*(216) -66 + j*(269) -252 + j*(84) -152 + j*(-173) --115 + j*(-153) --155 + j*(78) -22 + j*(159) -121 + j*(59) -110 + j*(-18) -107 + j*(-64) -78 + j*(-160) --71 + j*(-231) --272 + j*(-127) --298 + j*(153) --40 + j*(322) -209 + j*(154) -129 + j*(-89) --78 + j*(-45) --30 + j*(139) -154 + j*(100) -146 + j*(-78) -5 + j*(-105) --30 + j*(-6) -42 + j*(25) -78 + j*(-33) -49 + j*(-81) -10 + j*(-93) --25 + j*(-88) --45 + j*(-66) --37 + j*(-63) --71 + j*(-98) --168 + j*(-62) --174 + j*(75) --57 + j*(114) --51 + j*(44) --114 + j*(128) -53 + j*(245) -244 + j*(46) -56 + j*(-189) --183 + j*(-27) --54 + j*(180) -86 + j*(95) -33 + j*(69) -147 + j*(130) -258 + j*(-103) --43 + j*(-267) --233 + j*(59) -105 + j*(238) -250 + j*(-105) --94 + j*(-200) --133 + j*(144) -221 + j*(134) -185 + j*(-224) --156 + j*(-179) --106 + j*(123) -157 + j*(67) -100 + j*(-156) --79 + j*(-107) --30 + j*(28) -83 + j*(-28) -36 + j*(-136) --61 + j*(-124) --77 + j*(-66) --62 + j*(-59) --79 + j*(-62) --92 + j*(-49) --110 + j*(-57) --182 + j*(-35) --214 + j*(95) --91 + j*(204) -60 + j*(141) -56 + j*(3) --45 + j*(-40) --129 + j*(17) --141 + j*(137) --25 + j*(233) -122 + j*(161) -86 + j*(21) --23 + j*(67) -54 + j*(190) -211 + j*(124) -212 + j*(-29) -135 + j*(-88) -77 + j*(-112) --6 + j*(-95) --18 + j*(2) -88 + j*(3) -71 + j*(-130) --93 + j*(-113) --89 + j*(60) -63 + j*(59) -40 + j*(-63) --64 + j*(4) -46 + j*(124) -199 + j*(3) -110 + j*(-165) --14 + j*(-121) -27 + j*(-78) --1 + j*(-172) --158 + j*(-121) --114 + j*(62) -56 + j*(11) --25 + j*(-129) --136 + j*(-5) -47 + j*(67) -91 + j*(-194) --243 + j*(-243) --317 + j*(116) -11 + j*(177) -3 + j*(-127) --325 + j*(-47) --234 + j*(315) -100 + j*(265) -64 + j*(33) --65 + j*(122) -97 + j*(205) -181 + j*(7) --6 + j*(-79) --92 + j*(75) -12 + j*(163) -88 + j*(139) -138 + j*(116) -185 + j*(54) -168 + j*(-6) -181 + j*(-8) -240 + j*(-107) -139 + j*(-284) --102 + j*(-268) --188 + j*(-57) --70 + j*(79) -58 + j*(59) -124 + j*(-29) -103 + j*(-166) --71 + j*(-239) --239 + j*(-76) --129 + j*(154) -112 + j*(103) -102 + j*(-105) --44 + j*(-100) -5 + j*(-24) -39 + j*(-165) --192 + j*(-214) --280 + j*(54) --28 + j*(146) -11 + j*(-100) --272 + j*(-77) --240 + j*(257) -103 + j*(257) -129 + j*(-45) --126 + j*(-84) --192 + j*(124) --57 + j*(243) -98 + j*(217) -176 + j*(70) -47 + j*(-66) --117 + j*(63) -3 + j*(264) -213 + j*(202) -236 + j*(78) -286 + j*(42) -349 + j*(-157) -115 + j*(-352) --127 + j*(-173) -20 + j*(19) -157 + j*(-155) --40 + j*(-293) --196 + j*(-150) --152 + j*(-35) --146 + j*(-13) --134 + j*(73) --30 + j*(105) -13 + j*(47) -10 + j*(41) -62 + j*(22) -60 + j*(-71) --35 + j*(-108) --110 + j*(-59) --139 + j*(27) --74 + j*(130) -66 + j*(100) -47 + j*(-45) --98 + j*(-1) --24 + j*(165) -166 + j*(89) -119 + j*(-95) --11 + j*(-73) -14 + j*(-10) -33 + j*(-52) --2 + j*(-54) -25 + j*(-62) --21 + j*(-153) --182 + j*(-127) --233 + j*(45) --139 + j*(170) -1 + j*(206) -148 + j*(111) -108 + j*(-99) --129 + j*(-91) --134 + j*(153) -90 + j*(165) -76 + j*(2) --10 + j*(93) -205 + j*(142) -282 + j*(-177) --66 + j*(-310) --218 + j*(-15) -1 + j*(78) --14 + j*(-107) --235 + j*(-4) --125 + j*(271) -153 + j*(228) -177 + j*(35) -113 + j*(18) -173 + j*(6) -194 + j*(-136) -57 + j*(-248) --127 + j*(-214) --227 + j*(-45) --142 + j*(150) -74 + j*(161) -149 + j*(-24) -10 + j*(-123) --74 + j*(-17) -27 + j*(42) -69 + j*(-86) --99 + j*(-143) --210 + j*(53) --30 + j*(233) -194 + j*(115) -153 + j*(-89) -27 + j*(-88) -62 + j*(-47) -72 + j*(-163) --100 + j*(-204) --189 + j*(-44) --81 + j*(39) --68 + j*(-37) --172 + j*(21) --89 + j*(191) -129 + j*(135) -123 + j*(-83) --49 + j*(-111) --71 + j*(-8) --25 + j*(-44) --149 + j*(-86) --254 + j*(98) --92 + j*(288) -134 + j*(214) -148 + j*(37) -54 + j*(-8) -28 + j*(28) -52 + j*(37) -73 + j*(12) -54 + j*(-32) -0 + j*(-33) --11 + j*(12) -13 + j*(13) --25 + j*(10) --30 + j*(112) -132 + j*(161) -252 + j*(-8) -144 + j*(-168) -29 + j*(-141) -30 + j*(-132) --53 + j*(-196) --215 + j*(-105) --197 + j*(113) --7 + j*(194) -131 + j*(92) -123 + j*(-40) -34 + j*(-86) --18 + j*(-30) -45 + j*(15) -116 + j*(-76) -27 + j*(-212) --169 + j*(-191) --255 + j*(8) --118 + j*(182) -92 + j*(132) -102 + j*(-62) --54 + j*(-100) --85 + j*(8) --28 + j*(4) --95 + j*(-16) --102 + j*(118) -75 + j*(128) -71 + j*(-64) --132 + j*(-17) --40 + j*(214) -228 + j*(106) -140 + j*(-165) --86 + j*(-104) --25 + j*(43) -59 + j*(-49) --69 + j*(-115) --153 + j*(-3) --126 + j*(90) --95 + j*(182) -64 + j*(298) -332 + j*(189) -383 + j*(-132) -158 + j*(-334) --75 + j*(-292) --163 + j*(-157) --159 + j*(-76) --169 + j*(-34) --181 + j*(57) --85 + j*(127) --28 + j*(52) --142 + j*(67) --79 + j*(303) -290 + j*(274) -351 + j*(-153) --33 + j*(-279) --140 + j*(3) -62 + j*(5) --73 + j*(-185) --316 + j*(36) --100 + j*(343) -207 + j*(205) -150 + j*(-18) -44 + j*(9) -76 + j*(36) -62 + j*(19) -93 + j*(89) -264 + j*(37) -279 + j*(-225) -16 + j*(-364) --221 + j*(-199) --173 + j*(59) -66 + j*(86) -129 + j*(-153) --130 + j*(-253) --272 + j*(4) --43 + j*(154) -59 + j*(-58) --181 + j*(-96) --188 + j*(203) -158 + j*(231) -231 + j*(-121) --78 + j*(-242) --231 + j*(-1) --73 + j*(164) -84 + j*(79) -61 + j*(-66) --76 + j*(-97) --165 + j*(21) --100 + j*(154) -40 + j*(170) -131 + j*(82) -130 + j*(-43) -13 + j*(-129) --132 + j*(-51) --111 + j*(118) -43 + j*(163) -134 + j*(69) -128 + j*(-24) -84 + j*(-93) --4 + j*(-115) --61 + j*(-58) --43 + j*(-29) --78 + j*(-49) --159 + j*(25) --115 + j*(165) -18 + j*(211) -129 + j*(172) -212 + j*(86) -221 + j*(-52) -125 + j*(-137) -45 + j*(-125) -16 + j*(-107) --10 + j*(-80) -27 + j*(-62) -37 + j*(-163) --149 + j*(-210) --275 + j*(22) --55 + j*(215) -170 + j*(40) -67 + j*(-195) --156 + j*(-200) --302 + j*(-58) --322 + j*(194) --71 + j*(402) -238 + j*(243) -168 + j*(-30) -2 + j*(40) -160 + j*(127) -233 + j*(-122) --49 + j*(-212) --134 + j*(47) -83 + j*(91) -67 + j*(-90) --89 + j*(-14) -31 + j*(129) -164 + j*(5) -69 + j*(-88) -65 + j*(-21) -152 + j*(-116) -13 + j*(-266) --174 + j*(-155) --125 + j*(-5) --59 + j*(-30) --108 + j*(-16) --58 + j*(72) -64 + j*(13) -32 + j*(-130) --104 + j*(-166) --220 + j*(-107) --293 + j*(26) --243 + j*(204) --74 + j*(280) -58 + j*(226) -134 + j*(148) -170 + j*(0) -11 + j*(-155) --245 + j*(-18) --176 + j*(311) -156 + j*(342) -262 + j*(116) -193 + j*(44) -262 + j*(13) -243 + j*(-202) --38 + j*(-252) --123 + j*(7) -99 + j*(65) -106 + j*(-138) --89 + j*(-102) --18 + j*(80) -149 + j*(-20) -48 + j*(-172) --64 + j*(-101) --25 + j*(-78) --115 + j*(-115) --180 + j*(65) -54 + j*(159) -156 + j*(-105) --135 + j*(-199) --218 + j*(101) -74 + j*(163) -98 + j*(-118) --190 + j*(-112) --197 + j*(192) -77 + j*(262) -214 + j*(89) -193 + j*(-59) -103 + j*(-161) --49 + j*(-148) --66 + j*(-4) -71 + j*(-13) -25 + j*(-175) --161 + j*(-125) --121 + j*(42) --14 + j*(-19) --148 + j*(-78) --216 + j*(136) -24 + j*(252) -177 + j*(52) -52 + j*(-83) --16 + j*(-22) -18 + j*(-40) --71 + j*(-76) --123 + j*(59) -44 + j*(127) -129 + j*(-62) --69 + j*(-186) --238 + j*(-18) --142 + j*(175) -23 + j*(151) -30 + j*(36) --66 + j*(38) --69 + j*(160) -87 + j*(211) -202 + j*(57) -70 + j*(-105) --125 + j*(11) --36 + j*(258) -256 + j*(247) -360 + j*(-23) -197 + j*(-205) -21 + j*(-161) --1 + j*(-37) -98 + j*(21) -211 + j*(-69) -178 + j*(-262) --44 + j*(-342) --214 + j*(-179) --140 + j*(-1) --15 + j*(-43) --81 + j*(-137) --187 + j*(-45) --99 + j*(74) -3 + j*(-13) --115 + j*(-96) --217 + j*(71) --26 + j*(221) -170 + j*(42) -25 + j*(-180) --197 + j*(-85) --160 + j*(109) --40 + j*(117) --26 + j*(94) -37 + j*(112) -98 + j*(-15) --82 + j*(-117) --240 + j*(110) --1 + j*(338) -275 + j*(139) -134 + j*(-122) --68 + j*(-4) -70 + j*(153) -226 + j*(2) -109 + j*(-165) --36 + j*(-118) --52 + j*(-29) --26 + j*(29) -66 + j*(57) -154 + j*(-70) -16 + j*(-228) --197 + j*(-118) --143 + j*(106) -51 + j*(93) -57 + j*(-57) --50 + j*(-73) --76 + j*(-7) --59 + j*(15) --70 + j*(35) --49 + j*(91) -35 + j*(104) -85 + j*(16) --7 + j*(-52) --91 + j*(71) -88 + j*(199) -296 + j*(-21) -82 + j*(-317) --267 + j*(-149) --164 + j*(194) -119 + j*(135) -63 + j*(-51) --30 + j*(45) -124 + j*(87) -167 + j*(-99) -21 + j*(-161) --25 + j*(-115) --90 + j*(-147) --234 + j*(-19) --102 + j*(209) -148 + j*(103) -43 + j*(-117) --130 + j*(21) -50 + j*(173) -204 + j*(-17) -57 + j*(-162) --29 + j*(-80) -25 + j*(-93) --62 + j*(-186) --221 + j*(-114) --245 + j*(52) --156 + j*(170) --15 + j*(185) -43 + j*(71) --71 + j*(38) --92 + j*(211) -127 + j*(278) -246 + j*(107) -192 + j*(24) -250 + j*(10) -283 + j*(-182) -70 + j*(-308) --66 + j*(-182) --13 + j*(-148) --116 + j*(-216) --252 + j*(-37) --62 + j*(138) -112 + j*(-57) --100 + j*(-228) --281 + j*(-28) --136 + j*(136) --43 + j*(33) --157 + j*(18) --152 + j*(171) --5 + j*(194) -13 + j*(103) --39 + j*(147) -66 + j*(231) -209 + j*(132) -166 + j*(-13) -83 + j*(9) -156 + j*(37) -194 + j*(-104) -38 + j*(-194) --76 + j*(-85) --24 + j*(-7) --20 + j*(-30) --55 + j*(39) -60 + j*(112) -179 + j*(-3) -111 + j*(-139) -19 + j*(-146) --33 + j*(-150) --140 + j*(-105) --130 + j*(66) -59 + j*(73) -48 + j*(-127) --174 + j*(-85) --111 + j*(163) -148 + j*(89) -57 + j*(-166) --199 + j*(-43) --42 + j*(231) -268 + j*(74) -163 + j*(-266) --154 + j*(-243) --196 + j*(-18) --93 + j*(25) --111 + j*(3) --117 + j*(85) --22 + j*(112) --1 + j*(53) --16 + j*(87) -100 + j*(93) -138 + j*(-99) --95 + j*(-192) --242 + j*(38) --50 + j*(209) -101 + j*(59) --30 + j*(-54) --123 + j*(69) --38 + j*(158) -14 + j*(148) -58 + j*(201) -231 + j*(191) -325 + j*(-23) -185 + j*(-195) -45 + j*(-173) -7 + j*(-163) --122 + j*(-169) --247 + j*(42) --34 + j*(297) -319 + j*(155) -280 + j*(-231) --61 + j*(-281) --139 + j*(-29) -41 + j*(18) -45 + j*(-135) --93 + j*(-124) --81 + j*(-28) --38 + j*(-63) --110 + j*(-82) --141 + j*(-9) --116 + j*(16) --156 + j*(40) --140 + j*(154) --14 + j*(196) -58 + j*(135) -78 + j*(104) -120 + j*(43) -58 + j*(-41) --25 + j*(34) -86 + j*(121) -199 + j*(-7) -112 + j*(-131) -44 + j*(-110) -33 + j*(-158) --121 + j*(-179) --187 + j*(18) -6 + j*(85) -30 + j*(-119) --228 + j*(-107) --243 + j*(201) -52 + j*(291) -208 + j*(91) -141 + j*(-68) -42 + j*(-112) --58 + j*(-93) --100 + j*(0) --47 + j*(62) --12 + j*(48) --19 + j*(68) -38 + j*(112) -134 + j*(77) -177 + j*(-38) -98 + j*(-164) --70 + j*(-146) --91 + j*(26) -86 + j*(44) -100 + j*(-155) --105 + j*(-187) --153 + j*(-31) --88 + j*(-11) --148 + j*(4) --104 + j*(144) -77 + j*(93) -1 + j*(-83) --163 + j*(29) --42 + j*(179) -59 + j*(88) -6 + j*(103) -173 + j*(161) -295 + j*(-125) --27 + j*(-320) --240 + j*(-48) --51 + j*(89) --64 + j*(-56) --240 + j*(108) --5 + j*(366) -302 + j*(178) -229 + j*(-81) -117 + j*(-100) -71 + j*(-159) --107 + j*(-115) --44 + j*(127) -263 + j*(4) -87 + j*(-390) --380 + j*(-223) --282 + j*(247) -94 + j*(209) -51 + j*(-11) --28 + j*(110) -204 + j*(122) -228 + j*(-181) --72 + j*(-256) --180 + j*(-27) --45 + j*(78) -35 + j*(24) -47 + j*(-24) -25 + j*(-95) --91 + j*(-107) --139 + j*(34) -9 + j*(113) -112 + j*(-32) --18 + j*(-163) --177 + j*(-57) --107 + j*(117) -78 + j*(79) -77 + j*(-130) --155 + j*(-194) --317 + j*(21) --192 + j*(254) -25 + j*(245) -75 + j*(124) -42 + j*(116) -113 + j*(134) -172 + j*(31) -92 + j*(-42) -69 + j*(21) -177 + j*(-21) -120 + j*(-209) --117 + j*(-191) --136 + j*(36) -48 + j*(42) -5 + j*(-117) --158 + j*(-22) --24 + j*(159) -185 + j*(-5) -11 + j*(-269) --325 + j*(-140) --317 + j*(235) --3 + j*(373) -219 + j*(210) -212 + j*(26) -151 + j*(-43) -105 + j*(-101) --23 + j*(-127) --122 + j*(30) -38 + j*(196) -255 + j*(71) -202 + j*(-150) -57 + j*(-155) -62 + j*(-115) -39 + j*(-182) --60 + j*(-165) --47 + j*(-109) --64 + j*(-175) --222 + j*(-132) --204 + j*(82) -8 + j*(83) -1 + j*(-105) --180 + j*(-86) --175 + j*(76) --64 + j*(91) --54 + j*(36) --90 + j*(42) --106 + j*(91) --60 + j*(166) -63 + j*(159) -100 + j*(40) -21 + j*(1) -16 + j*(33) -9 + j*(-4) --69 + j*(47) -34 + j*(168) -188 + j*(21) -13 + j*(-138) --121 + j*(76) -148 + j*(175) -223 + j*(-135) --93 + j*(-193) --115 + j*(88) -107 + j*(58) -14 + j*(-93) --54 + j*(69) -182 + j*(64) -148 + j*(-245) --184 + j*(-229) --210 + j*(34) --93 + j*(59) --148 + j*(106) --1 + j*(295) -303 + j*(149) -215 + j*(-178) --49 + j*(-133) -8 + j*(54) -163 + j*(-39) -81 + j*(-192) --59 + j*(-179) --118 + j*(-100) --118 + j*(-17) -254 + j*(-10) -76 + j*(-153) --18 + j*(-66) -47 + j*(-84) --64 + j*(-223) --321 + j*(-112) --313 + j*(218) --22 + j*(334) -153 + j*(167) -99 + j*(27) -22 + j*(46) -63 + j*(111) -179 + j*(66) -187 + j*(-107) -5 + j*(-195) --132 + j*(-49) --30 + j*(89) -84 + j*(16) -40 + j*(-76) --21 + j*(-76) --74 + j*(-69) --136 + j*(7) --70 + j*(119) -35 + j*(62) --59 + j*(2) --95 + j*(186) -182 + j*(254) -316 + j*(-60) -25 + j*(-243) --161 + j*(4) -49 + j*(172) -197 + j*(2) -77 + j*(-119) -9 + j*(-37) -89 + j*(-21) -93 + j*(-126) --8 + j*(-157) --58 + j*(-104) --63 + j*(-88) --116 + j*(-65) --126 + j*(49) -14 + j*(114) -130 + j*(-16) -37 + j*(-168) --119 + j*(-136) --157 + j*(-20) --112 + j*(59) --28 + j*(83) -31 + j*(3) --67 + j*(-66) --148 + j*(71) -28 + j*(179) -158 + j*(-12) --24 + j*(-141) --117 + j*(20) -31 + j*(50) --12 + j*(-100) --171 + j*(-1) --35 + j*(156) -93 + j*(-4) --98 + j*(-98) --174 + j*(116) -35 + j*(187) -96 + j*(18) --18 + j*(-19) --39 + j*(40) --48 + j*(51) --66 + j*(136) -66 + j*(216) -198 + j*(115) -176 + j*(-5) -137 + j*(-35) -116 + j*(-69) -88 + j*(-67) -142 + j*(-100) -82 + j*(-290) --246 + j*(-293) --373 + j*(76) --87 + j*(290) -103 + j*(158) -93 + j*(109) -226 + j*(86) -247 + j*(-175) --47 + j*(-240) --90 + j*(38) -199 + j*(8) -119 + j*(-333) --255 + j*(-281) --264 + j*(42) --71 + j*(64) --111 + j*(-4) --120 + j*(132) -69 + j*(139) -86 + j*(-52) --85 + j*(-52) --62 + j*(112) -108 + j*(74) -86 + j*(-99) --75 + j*(-96) --78 + j*(42) -48 + j*(34) -23 + j*(-105) --137 + j*(-85) --141 + j*(82) --5 + j*(100) --5 + j*(16) --49 + j*(69) -77 + j*(88) -92 + j*(-113) --182 + j*(-150) --276 + j*(168) -23 + j*(330) -208 + j*(107) -64 + j*(-23) -19 + j*(103) -180 + j*(107) -218 + j*(-68) -98 + j*(-160) -4 + j*(-145) --81 + j*(-99) --108 + j*(50) -88 + j*(154) -288 + j*(-64) -101 + j*(-367) --256 + j*(-279) --276 + j*(37) --73 + j*(96) --68 + j*(-6) --135 + j*(78) -10 + j*(161) -100 + j*(9) --40 + j*(-54) --47 + j*(86) -120 + j*(31) -17 + j*(-182) --261 + j*(-69) --202 + j*(252) -85 + j*(308) -233 + j*(171) -313 + j*(39) -313 + j*(-197) -59 + j*(-351) --148 + j*(-180) --38 + j*(-49) --19 + j*(-190) --227 + j*(-170) --216 + j*(52) --65 + j*(30) --182 + j*(-33) --238 + j*(215) -83 + j*(325) -241 + j*(23) -12 + j*(-115) --50 + j*(55) -91 + j*(32) --6 + j*(-98) --127 + j*(57) -63 + j*(179) -190 + j*(-16) -9 + j*(-130) --76 + j*(42) -98 + j*(110) -183 + j*(-63) -37 + j*(-179) --99 + j*(-83) --46 + j*(57) -93 + j*(35) -106 + j*(-106) --13 + j*(-163) --94 + j*(-113) --136 + j*(-58) --165 + j*(54) --32 + j*(177) -162 + j*(64) -71 + j*(-158) --149 + j*(-78) --66 + j*(133) -136 + j*(49) -71 + j*(-140) --71 + j*(-119) --86 + j*(-66) --157 + j*(-65) --223 + j*(89) --69 + j*(231) -83 + j*(136) -29 + j*(52) -28 + j*(136) -187 + j*(112) -212 + j*(-88) -43 + j*(-182) --72 + j*(-89) --44 + j*(-6) --4 + j*(-25) --49 + j*(-52) --112 + j*(14) --66 + j*(126) -68 + j*(138) -146 + j*(37) -121 + j*(-84) --1 + j*(-151) --154 + j*(-57) --107 + j*(158) -141 + j*(159) -177 + j*(-77) --22 + j*(-104) -13 + j*(62) -192 + j*(-56) -21 + j*(-290) --262 + j*(-132) --165 + j*(151) -51 + j*(113) -37 + j*(-5) -8 + j*(18) -48 + j*(-3) -5 + j*(-36) -13 + j*(17) -94 + j*(-44) --9 + j*(-171) --174 + j*(-58) --77 + j*(116) -74 + j*(33) --8 + j*(-82) --98 + j*(-1) --31 + j*(72) -20 + j*(40) -21 + j*(30) -64 + j*(12) -51 + j*(-73) --57 + j*(-83) --91 + j*(29) -23 + j*(86) -109 + j*(-33) --9 + j*(-166) --200 + j*(-70) --149 + j*(159) -74 + j*(156) -83 + j*(-26) --53 + j*(5) -53 + j*(127) -204 + j*(-57) --27 + j*(-267) --308 + j*(-41) --140 + j*(284) -176 + j*(204) -175 + j*(-47) -9 + j*(-84) --35 + j*(17) -29 + j*(69) -103 + j*(41) -121 + j*(-43) -66 + j*(-91) -41 + j*(-82) -42 + j*(-129) --63 + j*(-180) --174 + j*(-76) --117 + j*(28) --91 + j*(-16) --206 + j*(47) --128 + j*(283) -193 + j*(266) -258 + j*(-54) --4 + j*(-167) --118 + j*(26) -6 + j*(127) -75 + j*(84) -110 + j*(81) -209 + j*(21) -190 + j*(-151) -24 + j*(-204) --61 + j*(-107) --36 + j*(-48) --18 + j*(-37) -16 + j*(-31) -38 + j*(-91) --39 + j*(-144) --117 + j*(-92) --119 + j*(-35) --132 + j*(4) --97 + j*(93) -38 + j*(78) -30 + j*(-82) --153 + j*(-69) --146 + j*(127) -32 + j*(129) -7 + j*(-2) --95 + j*(94) -70 + j*(228) -284 + j*(57) -206 + j*(-215) --42 + j*(-288) --244 + j*(-165) --298 + j*(76) --113 + j*(277) -151 + j*(194) -148 + j*(-52) --52 + j*(-83) --88 + j*(83) -62 + j*(131) -139 + j*(-5) -27 + j*(-122) --129 + j*(-40) --79 + j*(156) -146 + j*(141) -173 + j*(-105) --63 + j*(-176) --173 + j*(10) --83 + j*(117) --54 + j*(129) --1 + j*(231) -201 + j*(235) -281 + j*(44) -183 + j*(-27) -228 + j*(15) -324 + j*(-140) -168 + j*(-317) -9 + j*(-233) -95 + j*(-191) -66 + j*(-401) --260 + j*(-458) --479 + j*(-179) --404 + j*(89) --280 + j*(207) --132 + j*(310) -119 + j*(280) -226 + j*(27) -56 + j*(-135) --73 + j*(-43) --4 + j*(4) --29 + j*(-98) --199 + j*(-45) --175 + j*(177) -49 + j*(215) -124 + j*(40) -13 + j*(-30) --31 + j*(44) -29 + j*(79) -76 + j*(40) -74 + j*(-19) -21 + j*(-52) --27 + j*(-10) -15 + j*(32) -49 + j*(-23) --18 + j*(-55) --40 + j*(7) -6 + j*(-1) --54 + j*(-41) --117 + j*(76) -35 + j*(183) -183 + j*(40) -79 + j*(-119) --56 + j*(-58) --21 + j*(38) -50 + j*(14) -41 + j*(-52) --28 + j*(-80) --106 + j*(-21) --86 + j*(90) -12 + j*(117) -50 + j*(80) -88 + j*(90) -192 + j*(17) -143 + j*(-177) --98 + j*(-196) --193 + j*(33) --33 + j*(197) -168 + j*(150) -250 + j*(-32) -138 + j*(-204) --47 + j*(-156) -9 + j*(-8) -151 + j*(-147) --70 + j*(-351) --349 + j*(-124) --182 + j*(161) -18 + j*(32) --139 + j*(-53) --158 + j*(165) -86 + j*(170) -72 + j*(-34) --64 + j*(42) -110 + j*(148) -255 + j*(-100) -24 + j*(-322) --247 + j*(-218) --320 + j*(-6) --276 + j*(197) --72 + j*(337) -158 + j*(236) -158 + j*(52) -81 + j*(40) -131 + j*(45) -138 + j*(-57) -52 + j*(-81) -54 + j*(-54) -50 + j*(-128) --89 + j*(-151) --167 + j*(-4) --62 + j*(112) -55 + j*(58) -35 + j*(-46) --64 + j*(-44) --78 + j*(58) -19 + j*(84) -42 + j*(1) --32 + j*(1) --6 + j*(69) -49 + j*(25) --19 + j*(8) -16 + j*(121) -192 + j*(54) -127 + j*(-167) --102 + j*(-120) --66 + j*(75) -74 + j*(30) -8 + j*(-43) -1 + j*(54) -139 + j*(17) -100 + j*(-153) --66 + j*(-147) --98 + j*(-37) --68 + j*(16) --15 + j*(61) -84 + j*(8) -28 + j*(-129) --129 + j*(-59) --46 + j*(98) -94 + j*(-8) --35 + j*(-121) --118 + j*(24) -33 + j*(71) -48 + j*(-83) --100 + j*(-80) --98 + j*(34) --57 + j*(25) --103 + j*(65) --9 + j*(173) -144 + j*(78) -78 + j*(-78) --37 + j*(-34) -0 + j*(20) --2 + j*(-29) --74 + j*(18) --7 + j*(117) -107 + j*(59) -73 + j*(-45) -1 + j*(-21) -39 + j*(28) -100 + j*(-18) -72 + j*(-114) --42 + j*(-136) --112 + j*(-36) --37 + j*(57) -66 + j*(1) -25 + j*(-115) --92 + j*(-118) --153 + j*(-37) --148 + j*(53) --81 + j*(117) -6 + j*(95) --6 + j*(8) --119 + j*(34) --115 + j*(215) -116 + j*(305) -327 + j*(112) -244 + j*(-161) -6 + j*(-180) --41 + j*(-23) -54 + j*(-16) -8 + j*(-91) --58 + j*(-13) -45 + j*(30) -57 + j*(-109) --122 + j*(-103) --122 + j*(91) -43 + j*(95) -12 + j*(-2) --17 + j*(115) -218 + j*(117) -244 + j*(-215) --125 + j*(-296) --244 + j*(61) -66 + j*(191) -192 + j*(-68) --1 + j*(-185) --94 + j*(-71) --57 + j*(-23) --71 + j*(-9) --31 + j*(62) -89 + j*(21) -81 + j*(-135) --74 + j*(-192) --194 + j*(-103) --212 + j*(11) --192 + j*(98) --140 + j*(192) --10 + j*(256) -150 + j*(190) -185 + j*(32) -104 + j*(-49) -66 + j*(-52) -30 + j*(-100) --106 + j*(-81) --137 + j*(122) -101 + j*(227) -299 + j*(7) -167 + j*(-274) --129 + j*(-287) --291 + j*(-65) --211 + j*(175) -12 + j*(243) -161 + j*(110) -141 + j*(-30) -76 + j*(-87) -0 + j*(-122) --113 + j*(-66) --84 + j*(83) -66 + j*(64) -27 + j*(-73) --97 + j*(8) -37 + j*(119) -139 + j*(-71) --106 + j*(-170) --213 + j*(111) -76 + j*(228) -186 + j*(-36) --42 + j*(-121) --96 + j*(71) -56 + j*(107) -79 + j*(19) -66 + j*(16) -92 + j*(-28) -16 + j*(-65) -13 + j*(39) -163 + j*(-16) -59 + j*(-238) --233 + j*(-105) --89 + j*(243) -305 + j*(105) -205 + j*(-313) --194 + j*(-281) --226 + j*(44) --6 + j*(103) -47 + j*(-24) --11 + j*(-57) --18 + j*(-42) --17 + j*(-63) --56 + j*(-95) --145 + j*(-77) --183 + j*(60) --34 + j*(148) -72 + j*(-6) --105 + j*(-104) --199 + j*(105) -18 + j*(197) -80 + j*(-12) --137 + j*(-14) --93 + j*(242) -199 + j*(199) -197 + j*(-86) --37 + j*(-129) --113 + j*(28) --45 + j*(131) -69 + j*(158) -174 + j*(63) -106 + j*(-69) --1 + j*(5) -128 + j*(93) -242 + j*(-97) -55 + j*(-266) --127 + j*(-158) --124 + j*(-42) --134 + j*(18) --73 + j*(149) -127 + j*(127) -139 + j*(-74) --11 + j*(-93) --3 + j*(-16) -10 + j*(-75) --98 + j*(-40) --27 + j*(89) -96 + j*(-18) --55 + j*(-123) --149 + j*(67) -45 + j*(164) -137 + j*(19) -86 + j*(-37) -105 + j*(-89) --21 + j*(-194) --181 + j*(-13) -57 + j*(156) -234 + j*(-164) --155 + j*(-371) --403 + j*(13) --110 + j*(256) -44 + j*(81) --47 + j*(73) -78 + j*(133) -125 + j*(-73) --116 + j*(-96) --110 + j*(153) -117 + j*(132) -90 + j*(-28) -31 + j*(24) -131 + j*(-12) -42 + j*(-148) --80 + j*(-46) -35 + j*(4) --16 + j*(-148) --221 + j*(-10) --23 + j*(239) -247 + j*(18) -35 + j*(-240) --163 + j*(-67) --24 + j*(13) --80 + j*(-137) --294 + j*(2) --169 + j*(264) -54 + j*(219) -59 + j*(127) -112 + j*(136) -174 + j*(1) -14 + j*(-87) --62 + j*(85) -124 + j*(143) -178 + j*(-30) -48 + j*(-71) -57 + j*(12) -126 + j*(-59) -17 + j*(-147) --106 + j*(-33) --15 + j*(132) -194 + j*(95) -240 + j*(-132) -50 + j*(-254) --88 + j*(-122) -29 + j*(-28) -99 + j*(-187) --95 + j*(-300) --267 + j*(-153) --228 + j*(6) --156 + j*(41) --122 + j*(45) --116 + j*(18) --200 + j*(42) --203 + j*(222) -21 + j*(305) -157 + j*(124) -35 + j*(19) -1 + j*(133) -151 + j*(129) -161 + j*(-35) -23 + j*(-59) -8 + j*(44) -104 + j*(49) -136 + j*(-48) -61 + j*(-132) --68 + j*(-103) --92 + j*(47) -61 + j*(115) -170 + j*(-22) -78 + j*(-151) --27 + j*(-126) --45 + j*(-93) --95 + j*(-88) --137 + j*(16) --23 + j*(93) -66 + j*(-27) --81 + j*(-129) --231 + j*(39) --94 + j*(255) -139 + j*(207) -181 + j*(49) -168 + j*(5) -231 + j*(-105) -105 + j*(-317) --192 + j*(-274) --228 + j*(-6) --57 + j*(23) --119 + j*(-89) --247 + j*(63) --71 + j*(233) -102 + j*(82) --31 + j*(-52) --136 + j*(80) --28 + j*(187) -78 + j*(155) -148 + j*(89) -148 + j*(-62) --52 + j*(-130) --185 + j*(100) -29 + j*(301) -266 + j*(177) -280 + j*(9) -292 + j*(-85) -248 + j*(-291) --40 + j*(-396) --267 + j*(-170) --177 + j*(76) --1 + j*(95) -80 + j*(14) -73 + j*(-90) --40 + j*(-127) --90 + j*(-12) -42 + j*(26) -76 + j*(-139) --103 + j*(-202) --210 + j*(-71) --193 + j*(36) --164 + j*(129) --33 + j*(216) -126 + j*(130) -117 + j*(-5) -87 + j*(-40) -73 + j*(-141) --123 + j*(-200) --259 + j*(21) --77 + j*(185) -45 + j*(64) --32 + j*(29) -25 + j*(78) -39 + j*(-61) --186 + j*(-27) --119 + j*(289) -267 + j*(222) -222 + j*(-170) --119 + j*(-139) --74 + j*(124) -100 + j*(53) -10 + j*(-36) -6 + j*(71) -132 + j*(1) -15 + j*(-147) --148 + j*(-28) --78 + j*(127) -16 + j*(134) -77 + j*(156) -214 + j*(111) -246 + j*(-65) -144 + j*(-152) -95 + j*(-178) --23 + j*(-248) --216 + j*(-129) --152 + j*(127) -95 + j*(122) -135 + j*(-69) -17 + j*(-143) --75 + j*(-119) --157 + j*(-23) --88 + j*(161) -169 + j*(155) -256 + j*(-113) -64 + j*(-281) --111 + j*(-223) --162 + j*(-124) --154 + j*(-61) --140 + j*(-59) --221 + j*(-59) --289 + j*(105) --129 + j*(254) -20 + j*(151) --62 + j*(88) --39 + j*(217) -130 + j*(165) -64 + j*(25) --11 + j*(163) -244 + j*(229) -377 + j*(-88) -127 + j*(-293) --59 + j*(-196) --95 + j*(-131) --170 + j*(-47) --93 + j*(93) -25 + j*(1) --151 + j*(-75) --233 + j*(204) -87 + j*(337) -245 + j*(80) -103 + j*(-13) -141 + j*(52) -190 + j*(-105) --16 + j*(-148) --7 + j*(62) -220 + j*(-32) -76 + j*(-298) --201 + j*(-168) --111 + j*(37) --32 + j*(-49) --175 + j*(-12) --93 + j*(198) -136 + j*(139) -124 + j*(-34) -64 + j*(-37) -95 + j*(-90) --20 + j*(-189) --171 + j*(-74) --114 + j*(78) --15 + j*(88) -44 + j*(83) -137 + j*(1) -63 + j*(-166) --142 + j*(-103) --74 + j*(103) -123 + j*(6) --6 + j*(-195) --221 + j*(-57) --105 + j*(156) -79 + j*(72) -19 + j*(-69) --80 + j*(-19) --35 + j*(44) -6 + j*(-13) --87 + j*(-61) --192 + j*(52) --112 + j*(243) -129 + j*(253) -236 + j*(35) -91 + j*(-115) --44 + j*(-27) -28 + j*(87) -164 + j*(11) -116 + j*(-182) --134 + j*(-210) --259 + j*(60) --3 + j*(262) -236 + j*(19) --20 + j*(-234) --297 + j*(56) -16 + j*(375) -365 + j*(76) -103 + j*(-260) --189 + j*(-14) -66 + j*(234) -293 + j*(-16) -82 + j*(-218) --50 + j*(-61) -93 + j*(-19) -71 + j*(-188) --122 + j*(-160) --113 + j*(14) -15 + j*(16) -16 + j*(-71) --30 + j*(-85) --64 + j*(-98) --147 + j*(-69) --159 + j*(56) --42 + j*(100) --10 + j*(16) --82 + j*(27) --41 + j*(112) -51 + j*(78) -37 + j*(17) -42 + j*(22) -63 + j*(-54) --76 + j*(-110) --168 + j*(71) -37 + j*(191) -164 + j*(-25) --70 + j*(-147) --192 + j*(117) -93 + j*(267) -295 + j*(3) -106 + j*(-244) --141 + j*(-170) --177 + j*(23) --72 + j*(125) -36 + j*(92) -20 + j*(3) --78 + j*(56) -6 + j*(214) -238 + j*(158) -263 + j*(-87) -98 + j*(-170) -50 + j*(-124) -33 + j*(-194) --156 + j*(-219) --292 + j*(2) --151 + j*(224) -63 + j*(221) -158 + j*(116) -206 + j*(26) -218 + j*(-108) -115 + j*(-239) --49 + j*(-247) --142 + j*(-158) --155 + j*(-78) --161 + j*(-39) --186 + j*(23) --165 + j*(136) --27 + j*(216) -141 + j*(137) -158 + j*(-59) --6 + j*(-153) --134 + j*(-54) --101 + j*(64) --33 + j*(65) --40 + j*(52) --20 + j*(94) -48 + j*(69) -9 + j*(-5) --81 + j*(67) -15 + j*(206) -206 + j*(132) -190 + j*(-62) -49 + j*(-74) -56 + j*(9) -117 + j*(-29) -82 + j*(-70) -109 + j*(-51) -172 + j*(-185) --23 + j*(-366) --314 + j*(-216) --270 + j*(88) --56 + j*(100) --87 + j*(-6) --153 + j*(111) -8 + j*(194) -96 + j*(55) -1 + j*(24) -62 + j*(109) -177 + j*(-33) --5 + j*(-171) --139 + j*(36) -106 + j*(148) -213 + j*(-146) --103 + j*(-272) --249 + j*(13) --27 + j*(144) -54 + j*(-21) --76 + j*(-47) --66 + j*(56) --2 + j*(21) --71 + j*(-16) --115 + j*(82) --36 + j*(163) -71 + j*(156) -151 + j*(59) -82 + j*(-78) --102 + j*(-16) --26 + j*(233) -302 + j*(174) -305 + j*(-202) --49 + j*(-272) --136 + j*(16) -96 + j*(71) -115 + j*(-139) --86 + j*(-150) --104 + j*(27) -35 + j*(42) -37 + j*(-70) --75 + j*(-55) --54 + j*(78) -115 + j*(75) -156 + j*(-124) --50 + j*(-234) --222 + j*(-63) --117 + j*(148) -104 + j*(119) -156 + j*(-89) --21 + j*(-228) --242 + j*(-114) --213 + j*(168) -88 + j*(238) -245 + j*(-41) -39 + j*(-260) --187 + j*(-162) --201 + j*(-8) --169 + j*(58) --125 + j*(132) --17 + j*(139) -13 + j*(47) --62 + j*(23) --98 + j*(83) --105 + j*(158) --29 + j*(301) -257 + j*(325) -447 + j*(-21) -163 + j*(-355) --231 + j*(-200) --208 + j*(164) -71 + j*(241) -204 + j*(75) -139 + j*(-61) -31 + j*(-52) -40 + j*(45) -155 + j*(26) -152 + j*(-117) -21 + j*(-144) --9 + j*(-71) --6 + j*(-77) --78 + j*(-23) -15 + j*(126) -240 + j*(30) -194 + j*(-238) --36 + j*(-265) --91 + j*(-148) --93 + j*(-141) --160 + j*(-93) --126 + j*(-5) --101 + j*(-31) --165 + j*(47) -11 + j*(185) -234 + j*(-70) --75 + j*(-383) --466 + j*(-63) --175 + j*(363) -235 + j*(107) -8 + j*(-264) --322 + j*(-86) --228 + j*(157) --153 + j*(132) --203 + j*(249) -27 + j*(402) -252 + j*(170) -44 + j*(-29) --88 + j*(217) -237 + j*(332) -385 + j*(-18) -80 + j*(-173) --9 + j*(91) -257 + j*(102) -236 + j*(-187) --31 + j*(-152) -47 + j*(62) -228 + j*(-81) -47 + j*(-245) --74 + j*(-57) -150 + j*(-21) -128 + j*(-331) --258 + j*(-325) --310 + j*(66) -21 + j*(145) -88 + j*(-127) --151 + j*(-194) --251 + j*(-11) --170 + j*(112) --82 + j*(139) --10 + j*(121) -11 + j*(64) --31 + j*(62) --7 + j*(124) -93 + j*(112) -126 + j*(6) -42 + j*(-59) --32 + j*(-1) -19 + j*(89) -142 + j*(49) -147 + j*(-100) -18 + j*(-167) --82 + j*(-115) --127 + j*(-44) --140 + j*(68) --24 + j*(180) -145 + j*(122) -173 + j*(-27) -119 + j*(-105) -63 + j*(-177) --92 + j*(-196) --182 + j*(-29) --30 + j*(71) -28 + j*(-77) --143 + j*(-95) --134 + j*(83) -23 + j*(35) --97 + j*(-97) --238 + j*(85) --45 + j*(245) -86 + j*(83) --67 + j*(37) --52 + j*(232) -197 + j*(238) -286 + j*(17) -182 + j*(-133) -50 + j*(-175) --86 + j*(-118) --106 + j*(40) -28 + j*(112) -120 + j*(37) -129 + j*(-43) -112 + j*(-134) --9 + j*(-215) --161 + j*(-141) --180 + j*(-4) --148 + j*(71) --98 + j*(168) -72 + j*(206) -185 + j*(52) -101 + j*(-66) -54 + j*(-49) -39 + j*(-105) --122 + j*(-78) --98 + j*(180) -253 + j*(181) -315 + j*(-221) --54 + j*(-357) --211 + j*(-95) --59 + j*(-6) --71 + j*(-112) --192 + j*(-51) --170 + j*(62) --144 + j*(98) --115 + j*(206) -75 + j*(272) -245 + j*(103) -181 + j*(-96) -48 + j*(-134) --18 + j*(-117) --96 + j*(-97) --159 + j*(6) --98 + j*(127) -32 + j*(123) -52 + j*(21) --45 + j*(25) --13 + j*(169) -207 + j*(154) -260 + j*(-107) -22 + j*(-226) --115 + j*(-51) -6 + j*(68) -105 + j*(-15) -75 + j*(-115) --16 + j*(-165) --156 + j*(-121) --179 + j*(66) -6 + j*(146) -101 + j*(-12) --24 + j*(-93) --80 + j*(9) -5 + j*(45) -41 + j*(-20) -14 + j*(-86) --86 + j*(-133) --232 + j*(-35) --189 + j*(170) --17 + j*(186) --16 + j*(129) -40 + j*(239) -302 + j*(142) -232 + j*(-231) --175 + j*(-193) --135 + j*(192) -209 + j*(107) -62 + j*(-202) --229 + j*(6) -7 + j*(298) -291 + j*(92) -164 + j*(-139) -38 + j*(-79) -85 + j*(-69) -36 + j*(-137) --35 + j*(-97) --25 + j*(-71) --74 + j*(-62) --58 + j*(52) -118 + j*(33) -110 + j*(-211) --180 + j*(-263) --324 + j*(4) --163 + j*(216) -29 + j*(197) -110 + j*(105) -139 + j*(16) -114 + j*(-91) --4 + j*(-152) --122 + j*(-69) --78 + j*(74) -77 + j*(49) -64 + j*(-122) --115 + j*(-130) --146 + j*(22) --57 + j*(50) --74 + j*(18) --73 + j*(103) -56 + j*(91) -34 + j*(-60) --123 + j*(-23) --85 + j*(131) -33 + j*(101) --1 + j*(56) -42 + j*(124) -165 + j*(4) --16 + j*(-183) --284 + j*(33) --88 + j*(383) -301 + j*(281) -313 + j*(-45) -132 + j*(-107) -120 + j*(-59) -117 + j*(-146) --25 + j*(-164) --78 + j*(-21) -50 + j*(42) -121 + j*(-77) -15 + j*(-170) --95 + j*(-87) --25 + j*(22) -95 + j*(-66) --10 + j*(-231) --231 + j*(-156) --216 + j*(67) --58 + j*(75) --108 + j*(-13) --192 + j*(141) -27 + j*(284) -223 + j*(67) -39 + j*(-119) --94 + j*(57) -118 + j*(142) -185 + j*(-107) --74 + j*(-174) --129 + j*(74) -108 + j*(103) -122 + j*(-139) --121 + j*(-174) --208 + j*(45) --54 + j*(185) -111 + j*(119) -115 + j*(-40) --29 + j*(-81) --82 + j*(69) -83 + j*(148) -202 + j*(0) -124 + j*(-132) -52 + j*(-143) -6 + j*(-183) --119 + j*(-177) --158 + j*(-59) --113 + j*(-46) --206 + j*(-45) --221 + j*(156) -25 + j*(206) -66 + j*(-45) --206 + j*(-42) --188 + j*(257) -80 + j*(268) -86 + j*(122) -84 + j*(221) -343 + j*(170) -361 + j*(-197) -23 + j*(-321) --142 + j*(-121) --106 + j*(-8) --95 + j*(71) -39 + j*(152) -164 + j*(8) -15 + j*(-106) --46 + j*(63) -163 + j*(71) -142 + j*(-177) --112 + j*(-150) --83 + j*(72) -87 + j*(40) -53 + j*(-65) -25 + j*(-30) -74 + j*(-76) --7 + j*(-144) --54 + j*(-71) -3 + j*(-107) --147 + j*(-208) --345 + j*(4) --169 + j*(287) -110 + j*(211) -119 + j*(41) -110 + j*(19) -148 + j*(-118) --73 + j*(-258) --314 + j*(-25) --127 + j*(276) -167 + j*(165) -117 + j*(-55) --4 + j*(-7) -100 + j*(40) -143 + j*(-129) --39 + j*(-216) --150 + j*(-91) --101 + j*(-23) --125 + j*(-52) --200 + j*(29) --144 + j*(153) --40 + j*(166) -11 + j*(151) -85 + j*(118) -91 + j*(-7) --61 + j*(-33) --100 + j*(148) -93 + j*(218) -199 + j*(59) -112 + j*(-40) -63 + j*(-27) -28 + j*(-44) --54 + j*(28) -35 + j*(182) -256 + j*(131) -306 + j*(-94) -187 + j*(-243) -21 + j*(-292) --157 + j*(-193) --129 + j*(25) -83 + j*(13) -42 + j*(-211) --204 + j*(-165) --187 + j*(63) --46 + j*(74) --51 + j*(54) -43 + j*(98) -112 + j*(-78) --137 + j*(-135) --150 + j*(200) -284 + j*(163) -214 + j*(-362) --363 + j*(-276) --255 + j*(302) -293 + j*(146) -83 + j*(-375) --423 + j*(-147) --228 + j*(315) -134 + j*(178) -39 + j*(-47) --64 + j*(32) --3 + j*(41) --75 + j*(15) --71 + j*(171) -154 + j*(167) -175 + j*(-86) --69 + j*(-142) --149 + j*(66) -4 + j*(169) -115 + j*(78) -75 + j*(-21) --17 + j*(6) -23 + j*(125) -205 + j*(89) -219 + j*(-150) --26 + j*(-232) --145 + j*(-30) -8 + j*(84) -98 + j*(-42) --12 + j*(-126) --103 + j*(-57) --100 + j*(23) --71 + j*(86) -13 + j*(136) -128 + j*(88) -135 + j*(-43) -35 + j*(-82) -3 + j*(-13) -74 + j*(-7) -74 + j*(-98) --23 + j*(-114) --48 + j*(-29) -23 + j*(-13) -37 + j*(-82) --19 + j*(-112) --54 + j*(-98) --83 + j*(-95) --122 + j*(-71) --146 + j*(-47) --209 + j*(-8) --245 + j*(141) --91 + j*(293) -115 + j*(228) -140 + j*(78) -114 + j*(45) -153 + j*(-23) -64 + j*(-152) --105 + j*(-92) --72 + j*(58) -28 + j*(18) --56 + j*(-42) --107 + j*(85) -36 + j*(156) -123 + j*(37) -47 + j*(-40) -1 + j*(1) -21 + j*(21) -24 + j*(16) -45 + j*(29) -75 + j*(-9) -35 + j*(-57) --26 + j*(-11) -36 + j*(71) -168 + j*(4) -137 + j*(-182) --62 + j*(-215) --121 + j*(-64) --18 + j*(-70) --149 + j*(-198) --399 + j*(23) --184 + j*(413) -272 + j*(271) -185 + j*(-159) --191 + j*(-66) --62 + j*(284) -279 + j*(151) -170 + j*(-151) --56 + j*(-49) -82 + j*(110) -231 + j*(-54) -95 + j*(-223) --56 + j*(-167) --69 + j*(-92) --76 + j*(-71) --86 + j*(-23) --50 + j*(15) --8 + j*(13) -24 + j*(-11) -33 + j*(-72) --23 + j*(-122) --91 + j*(-112) --129 + j*(-92) --197 + j*(-66) --251 + j*(42) --188 + j*(165) --86 + j*(171) --81 + j*(136) --107 + j*(202) --6 + j*(310) -184 + j*(270) -243 + j*(90) -127 + j*(6) -94 + j*(98) -244 + j*(95) -273 + j*(-111) -74 + j*(-185) -13 + j*(-28) -173 + j*(-26) -148 + j*(-244) --113 + j*(-246) --159 + j*(-1) -40 + j*(54) -84 + j*(-108) --50 + j*(-150) --100 + j*(-60) --72 + j*(-21) --64 + j*(3) --14 + j*(33) -53 + j*(-29) -1 + j*(-134) --134 + j*(-132) --203 + j*(-6) --136 + j*(125) -16 + j*(111) -16 + j*(-48) --190 + j*(-33) --182 + j*(265) -206 + j*(314) -344 + j*(-115) --71 + j*(-330) --330 + j*(21) --79 + j*(273) -98 + j*(139) -45 + j*(103) -168 + j*(148) -262 + j*(-77) -10 + j*(-212) --114 + j*(34) -141 + j*(115) -204 + j*(-159) --43 + j*(-242) --132 + j*(-90) --115 + j*(-62) --211 + j*(23) --103 + j*(257) -225 + j*(193) -228 + j*(-151) --64 + j*(-209) --135 + j*(-3) --9 + j*(37) --16 + j*(-38) --65 + j*(2) --9 + j*(28) --17 + j*(-59) --173 + j*(-44) --218 + j*(197) -60 + j*(376) -379 + j*(150) -269 + j*(-243) --109 + j*(-243) --162 + j*(63) -66 + j*(113) -81 + j*(-51) --37 + j*(-18) -35 + j*(69) -100 + j*(-15) -40 + j*(-34) -110 + j*(-2) -157 + j*(-185) --97 + j*(-291) --256 + j*(-37) --44 + j*(111) -45 + j*(-82) --172 + j*(-120) --209 + j*(113) --8 + j*(174) -56 + j*(55) -19 + j*(27) -41 + j*(8) --13 + j*(-49) --89 + j*(33) -17 + j*(125) -119 + j*(4) -6 + j*(-98) --88 + j*(-2) --11 + j*(70) -25 + j*(18) --7 + j*(28) -58 + j*(59) -112 + j*(-53) --15 + j*(-151) --150 + j*(-53) --114 + j*(76) --48 + j*(92) --37 + j*(117) -45 + j*(177) -184 + j*(117) -210 + j*(-41) -116 + j*(-142) -1 + j*(-157) --101 + j*(-91) --107 + j*(54) -39 + j*(117) -136 + j*(-5) -49 + j*(-109) --28 + j*(-47) -35 + j*(-3) -76 + j*(-88) --8 + j*(-164) --124 + j*(-138) --185 + j*(-31) --127 + j*(90) --1 + j*(72) --35 + j*(-47) --191 + j*(39) --83 + j*(275) -226 + j*(209) -233 + j*(-107) --24 + j*(-156) --54 + j*(23) -73 + j*(-1) -4 + j*(-107) --91 + j*(-16) -14 + j*(49) -49 + j*(-82) --109 + j*(-105) --136 + j*(57) -6 + j*(71) --23 + j*(-66) --205 + j*(0) --170 + j*(249) -99 + j*(314) -259 + j*(119) -187 + j*(-54) -83 + j*(-64) -80 + j*(-42) -74 + j*(-91) --12 + j*(-110) --60 + j*(-23) -15 + j*(33) -69 + j*(-41) --9 + j*(-100) --71 + j*(-27) --15 + j*(25) -7 + j*(-19) --36 + j*(-1) -28 + j*(59) -127 + j*(-49) --5 + j*(-206) --233 + j*(-87) --170 + j*(190) -111 + j*(216) -231 + j*(-8) -119 + j*(-180) --25 + j*(-201) --130 + j*(-160) --214 + j*(-70) --226 + j*(76) --125 + j*(190) -18 + j*(189) -89 + j*(100) -66 + j*(33) -50 + j*(39) -93 + j*(19) -85 + j*(-71) --31 + j*(-95) --86 + j*(21) -30 + j*(101) -147 + j*(-8) -78 + j*(-171) --108 + j*(-180) --200 + j*(-35) --151 + j*(91) --68 + j*(125) --8 + j*(127) -56 + j*(101) -77 + j*(23) -11 + j*(-21) --42 + j*(26) --31 + j*(79) --11 + j*(127) -71 + j*(201) -253 + j*(163) -330 + j*(-45) -214 + j*(-199) -112 + j*(-206) -83 + j*(-250) --57 + j*(-326) --268 + j*(-235) --325 + j*(4) --178 + j*(190) -42 + j*(175) -108 + j*(-13) --57 + j*(-97) --132 + j*(84) -90 + j*(159) -181 + j*(-96) --88 + j*(-200) --194 + j*(58) -47 + j*(148) -115 + j*(-77) --90 + j*(-131) --146 + j*(30) --64 + j*(77) --58 + j*(88) -11 + j*(163) -161 + j*(100) -155 + j*(-69) -41 + j*(-119) --9 + j*(-103) --74 + j*(-113) --176 + j*(-38) --165 + j*(134) -11 + j*(231) -211 + j*(119) -199 + j*(-142) --76 + j*(-228) --226 + j*(30) -9 + j*(209) -200 + j*(-6) -21 + j*(-205) --164 + j*(-93) --141 + j*(21) --167 + j*(45) --193 + j*(214) -25 + j*(373) -298 + j*(247) -339 + j*(-19) -193 + j*(-187) -6 + j*(-186) --74 + j*(-49) -9 + j*(35) -66 + j*(-16) -44 + j*(-30) -100 + j*(-42) -60 + j*(-196) --193 + j*(-154) --158 + j*(175) -229 + j*(144) -200 + j*(-293) --264 + j*(-284) --288 + j*(158) -83 + j*(194) -88 + j*(-88) --126 + j*(-33) --25 + j*(153) -156 + j*(48) -86 + j*(-111) --18 + j*(-86) --4 + j*(-40) -15 + j*(-69) --14 + j*(-108) --82 + j*(-122) --151 + j*(-66) --136 + j*(14) --91 + j*(25) --88 + j*(16) --79 + j*(6) --142 + j*(-51) --326 + j*(49) --298 + j*(388) -96 + j*(531) -383 + j*(238) -268 + j*(-56) -84 + j*(-71) -29 + j*(-13) -1 + j*(42) -54 + j*(143) -218 + j*(122) -266 + j*(-61) -140 + j*(-158) -66 + j*(-114) -79 + j*(-106) -57 + j*(-148) -2 + j*(-156) --47 + j*(-148) --113 + j*(-105) --115 + j*(8) -15 + j*(54) -98 + j*(-83) --35 + j*(-215) --214 + j*(-125) --200 + j*(57) --76 + j*(100) --28 + j*(53) --25 + j*(40) --6 + j*(14) --44 + j*(-23) --100 + j*(23) --60 + j*(91) --9 + j*(66) --38 + j*(46) --46 + j*(100) -6 + j*(135) -68 + j*(144) -162 + j*(107) -194 + j*(-35) -66 + j*(-109) -26 + j*(-7) -151 + j*(-57) -23 + j*(-262) --274 + j*(-100) --108 + j*(252) -257 + j*(83) -76 + j*(-270) --252 + j*(-71) --45 + j*(216) -184 + j*(10) --11 + j*(-144) --75 + j*(35) -95 + j*(13) -1 + j*(-161) --164 + j*(-30) --23 + j*(100) -51 + j*(-47) --111 + j*(-62) --88 + j*(113) -86 + j*(73) -46 + j*(-92) --112 + j*(-87) --181 + j*(48) --118 + j*(214) -111 + j*(260) -245 + j*(37) -64 + j*(-98) -10 + j*(86) -279 + j*(38) -194 + j*(-350) --269 + j*(-301) --269 + j*(151) -103 + j*(166) -97 + j*(-110) --85 + j*(-75) --29 + j*(7) --47 + j*(-75) --155 + j*(13) --47 + j*(115) --23 + j*(8) --161 + j*(115) -73 + j*(341) -402 + j*(43) -104 + j*(-348) --291 + j*(-73) --41 + j*(291) -286 + j*(80) -141 + j*(-188) --30 + j*(-125) --25 + j*(-79) --93 + j*(-71) --95 + j*(68) -67 + j*(79) -82 + j*(-76) --42 + j*(-91) --57 + j*(-19) --46 + j*(-17) --73 + j*(24) --16 + j*(76) -40 + j*(37) -27 + j*(22) -93 + j*(28) -146 + j*(-124) --43 + j*(-261) --264 + j*(-112) --212 + j*(122) --37 + j*(161) -26 + j*(78) -6 + j*(52) -33 + j*(64) -81 + j*(0) --1 + j*(-100) --160 + j*(-18) --111 + j*(191) -105 + j*(204) -164 + j*(69) -171 + j*(43) -288 + j*(-88) -132 + j*(-406) --337 + j*(-333) --398 + j*(167) -19 + j*(324) -200 + j*(46) -62 + j*(-95) --21 + j*(-85) --133 + j*(-71) --204 + j*(156) -99 + j*(325) -346 + j*(9) -52 + j*(-248) --148 + j*(45) -208 + j*(187) -358 + j*(-264) --139 + j*(-507) --506 + j*(-58) --180 + j*(391) -290 + j*(215) -249 + j*(-226) --124 + j*(-294) --255 + j*(-22) --95 + j*(107) --29 + j*(27) --74 + j*(37) --13 + j*(66) --13 + j*(-32) --161 + j*(-1) --132 + j*(199) -66 + j*(206) -91 + j*(81) -59 + j*(102) -163 + j*(83) -148 + j*(-71) -2 + j*(-67) -16 + j*(41) -86 + j*(13) -69 + j*(-12) -115 + j*(-17) -103 + j*(-153) --99 + j*(-158) --127 + j*(71) -85 + j*(114) -129 + j*(-27) -112 + j*(-34) -218 + j*(-152) -32 + j*(-427) --383 + j*(-278) --339 + j*(162) -15 + j*(195) -56 + j*(-23) --36 + j*(-38) --22 + j*(-61) --161 + j*(-107) --261 + j*(129) -12 + j*(298) -224 + j*(59) -70 + j*(-136) --52 + j*(-70) --47 + j*(-59) --140 + j*(-52) --154 + j*(98) --23 + j*(129) --24 + j*(57) --47 + j*(139) -116 + j*(153) -151 + j*(-49) --37 + j*(-100) --79 + j*(33) --25 + j*(25) --133 + j*(35) --129 + j*(269) -173 + j*(357) -363 + j*(115) -275 + j*(-83) -205 + j*(-116) -185 + j*(-214) -9 + j*(-309) --196 + j*(-190) --194 + j*(33) --32 + j*(125) -95 + j*(32) -40 + j*(-100) --120 + j*(-52) --76 + j*(165) -205 + j*(163) -271 + j*(-156) --33 + j*(-278) --160 + j*(-15) -83 + j*(70) -123 + j*(-186) --147 + j*(-210) --156 + j*(40) -52 + j*(11) --41 + j*(-169) --214 + j*(-28) --52 + j*(142) -107 + j*(-16) --21 + j*(-165) --147 + j*(-124) --230 + j*(-78) --342 + j*(105) --146 + j*(390) -249 + j*(259) -194 + j*(-158) --195 + j*(-152) --223 + j*(187) -37 + j*(253) -122 + j*(97) -56 + j*(23) --13 + j*(51) -5 + j*(165) -209 + j*(189) -316 + j*(-83) -35 + j*(-265) --167 + j*(-19) -47 + j*(158) -181 + j*(-25) -46 + j*(-106) -53 + j*(-27) -105 + j*(-142) --91 + j*(-211) --183 + j*(-4) --4 + j*(66) --1 + j*(-104) --207 + j*(-59) --187 + j*(189) -39 + j*(249) -162 + j*(117) -140 + j*(-4) -64 + j*(-35) -35 + j*(21) -118 + j*(47) -178 + j*(-62) -99 + j*(-157) -27 + j*(-137) -33 + j*(-146) --40 + j*(-216) --193 + j*(-161) --205 + j*(27) --36 + j*(80) -11 + j*(-88) --214 + j*(-137) --328 + j*(147) --54 + j*(356) -190 + j*(168) -86 + j*(-4) -30 + j*(81) -143 + j*(59) -93 + j*(-39) -91 + j*(59) -321 + j*(-57) -171 + j*(-471) --364 + j*(-392) --382 + j*(114) --21 + j*(144) --91 + j*(-66) --223 + j*(142) -67 + j*(259) -170 + j*(-28) --49 + j*(-78) --8 + j*(59) -57 + j*(-97) --209 + j*(-124) --242 + j*(199) -52 + j*(252) -82 + j*(60) -1 + j*(119) -163 + j*(142) -177 + j*(-79) --37 + j*(-81) --11 + j*(94) -128 + j*(43) -76 + j*(-49) -56 + j*(-5) -112 + j*(-57) -29 + j*(-132) --37 + j*(-64) -15 + j*(-53) --33 + j*(-123) --136 + j*(-69) --132 + j*(37) --85 + j*(86) --25 + j*(117) -38 + j*(82) -11 + j*(58) -51 + j*(136) -216 + j*(64) -161 + j*(-162) --64 + j*(-133) --36 + j*(40) -72 + j*(-15) --13 + j*(-60) -1 + j*(43) -103 + j*(-13) -25 + j*(-83) -36 + j*(16) -181 + j*(-104) --18 + j*(-312) --258 + j*(-88) --38 + j*(113) -69 + j*(-120) --192 + j*(-119) --91 + j*(164) -205 + j*(-31) --57 + j*(-346) --381 + j*(-87) --197 + j*(186) --54 + j*(93) --95 + j*(115) -54 + j*(133) -33 + j*(-93) --244 + j*(-11) --107 + j*(305) -207 + j*(138) -18 + j*(-119) --147 + j*(105) -119 + j*(175) -96 + j*(-133) --253 + j*(-41) --149 + j*(344) -222 + j*(285) -220 + j*(11) -82 + j*(6) -124 + j*(48) -144 + j*(-33) -71 + j*(-71) -6 + j*(-41) --13 + j*(59) -137 + j*(151) -328 + j*(-30) -182 + j*(-309) --106 + j*(-240) --87 + j*(-27) -31 + j*(-71) --78 + j*(-133) --141 + j*(31) -40 + j*(122) -172 + j*(-39) -65 + j*(-214) --133 + j*(-192) --195 + j*(-4) --39 + j*(106) -78 + j*(-33) --74 + j*(-144) --187 + j*(40) -24 + j*(165) -167 + j*(-59) --47 + j*(-227) --223 + j*(-54) --111 + j*(86) --56 + j*(2) --182 + j*(34) --129 + j*(248) -155 + j*(257) -254 + j*(-10) -76 + j*(-153) --18 + j*(-66) -47 + j*(-84) --64 + j*(-223) --321 + j*(-112) --313 + j*(218) --22 + j*(334) -153 + j*(167) -99 + j*(27) -22 + j*(46) -63 + j*(111) -179 + j*(66) -187 + j*(-107) -5 + j*(-195) --132 + j*(-49) --30 + j*(89) -84 + j*(16) -40 + j*(-76) --21 + j*(-76) --74 + j*(-69) --136 + j*(7) --70 + j*(119) -35 + j*(62) --59 + j*(2) --95 + j*(186) -182 + j*(254) -316 + j*(-60) -25 + j*(-243) --161 + j*(4) -49 + j*(172) -197 + j*(2) -77 + j*(-119) -9 + j*(-37) -89 + j*(-21) -93 + j*(-126) --8 + j*(-157) --58 + j*(-104) --63 + j*(-88) --116 + j*(-65) --126 + j*(49) -14 + j*(114) -130 + j*(-16) -37 + j*(-168) --119 + j*(-136) --157 + j*(-20) --112 + j*(59) --28 + j*(83) -31 + j*(3) --67 + j*(-66) --148 + j*(71) -28 + j*(179) -158 + j*(-12) --24 + j*(-141) --117 + j*(20) -31 + j*(50) --12 + j*(-100) --171 + j*(-1) --35 + j*(156) -93 + j*(-4) --98 + j*(-98) --174 + j*(116) -35 + j*(187) -96 + j*(18) --18 + j*(-19) --39 + j*(40) --48 + j*(51) --66 + j*(136) -66 + j*(216) -198 + j*(115) -176 + j*(-5) -137 + j*(-35) -116 + j*(-69) -88 + j*(-67) -142 + j*(-100) -82 + j*(-290) --246 + j*(-293) --373 + j*(76) --87 + j*(290) -103 + j*(158) -93 + j*(109) -226 + j*(86) -247 + j*(-175) --47 + j*(-240) --90 + j*(38) -199 + j*(8) -119 + j*(-333) --255 + j*(-281) --264 + j*(42) --71 + j*(64) --111 + j*(-4) --120 + j*(132) -69 + j*(139) -86 + j*(-52) --85 + j*(-52) --62 + j*(112) -108 + j*(74) -86 + j*(-99) --75 + j*(-96) --78 + j*(42) -48 + j*(34) -23 + j*(-105) --137 + j*(-85) --141 + j*(82) --5 + j*(100) --5 + j*(16) --49 + j*(69) -77 + j*(88) -92 + j*(-113) --182 + j*(-150) --276 + j*(168) -23 + j*(330) -208 + j*(107) -64 + j*(-23) -19 + j*(103) -180 + j*(107) -218 + j*(-68) -98 + j*(-160) -4 + j*(-145) --81 + j*(-99) --108 + j*(50) -88 + j*(154) -288 + j*(-64) -101 + j*(-367) --256 + j*(-279) --276 + j*(37) --73 + j*(96) --68 + j*(-6) --135 + j*(78) -10 + j*(161) -100 + j*(9) --40 + j*(-54) --47 + j*(86) -120 + j*(31) -17 + j*(-182) --261 + j*(-69) --202 + j*(252) -85 + j*(308) -233 + j*(171) -313 + j*(39) -313 + j*(-197) -59 + j*(-351) --148 + j*(-180) --38 + j*(-49) --81 + j*(-46) --16 + j*(85) -103 + j*(-8) --16 + j*(-98) --54 + j*(54) -149 + j*(39) -102 + j*(-221) --192 + j*(-181) --167 + j*(105) -78 + j*(81) -42 + j*(-127) --145 + j*(-88) --132 + j*(79) -8 + j*(108) -81 + j*(4) -7 + j*(-110) --141 + j*(-67) --123 + j*(97) -32 + j*(84) --13 + j*(-54) --156 + j*(39) --35 + j*(213) -158 + j*(103) -86 + j*(-72) --36 + j*(-31) --8 + j*(33) -12 + j*(3) --18 + j*(3) --26 + j*(21) --40 + j*(49) --1 + j*(110) -91 + j*(77) -57 + j*(-6) -1 + j*(72) -150 + j*(144) -295 + j*(-41) -176 + j*(-265) --59 + j*(-291) --229 + j*(-135) --201 + j*(130) -114 + j*(213) -281 + j*(-125) --55 + j*(-348) --282 + j*(-45) --9 + j*(112) -31 + j*(-186) --354 + j*(-137) --294 + j*(325) -173 + j*(303) -168 + j*(-91) --138 + j*(-62) --81 + j*(177) -95 + j*(133) -79 + j*(59) -144 + j*(83) -242 + j*(-95) -37 + j*(-299) --247 + j*(-161) --223 + j*(132) -5 + j*(216) -146 + j*(88) -110 + j*(-48) -15 + j*(-57) -13 + j*(1) -62 + j*(-21) -42 + j*(-80) --10 + j*(-93) --57 + j*(-95) --132 + j*(-48) --117 + j*(71) --4 + j*(81) --21 + j*(-1) --98 + j*(76) -10 + j*(199) -175 + j*(142) -238 + j*(12) -245 + j*(-152) -62 + j*(-344) --260 + j*(-221) --199 + j*(131) -117 + j*(80) -23 + j*(-192) --208 + j*(-39) --1 + j*(132) -88 + j*(-134) --250 + j*(-153) --228 + j*(236) -160 + j*(183) -52 + j*(-163) --254 + j*(30) -9 + j*(329) -326 + j*(51) -100 + j*(-272) --187 + j*(-156) --197 + j*(35) --144 + j*(139) --6 + j*(221) -158 + j*(98) -41 + j*(-88) --153 + j*(50) --9 + j*(281) -256 + j*(204) -310 + j*(-22) -224 + j*(-184) -53 + j*(-279) --167 + j*(-194) --196 + j*(51) --12 + j*(165) -132 + j*(88) -176 + j*(-17) -170 + j*(-149) -28 + j*(-263) --156 + j*(-184) --144 + j*(-11) --22 + j*(-8) --47 + j*(-112) --171 + j*(-77) --164 + j*(60) --51 + j*(81) --47 + j*(-8) --152 + j*(21) --140 + j*(176) -28 + j*(229) -139 + j*(130) -151 + j*(42) -165 + j*(-37) -103 + j*(-161) --70 + j*(-179) --158 + j*(-38) --97 + j*(66) --30 + j*(76) -13 + j*(75) -59 + j*(37) -47 + j*(-21) -20 + j*(-23) -34 + j*(-53) --50 + j*(-124) --206 + j*(-18) --139 + j*(218) -118 + j*(235) -202 + j*(41) -112 + j*(-37) -115 + j*(-7) -166 + j*(-97) -58 + j*(-223) --95 + j*(-175) --90 + j*(-58) --28 + j*(-78) --98 + j*(-123) --185 + j*(-47) --167 + j*(49) --157 + j*(98) --117 + j*(235) -140 + j*(299) -325 + j*(19) -93 + j*(-212) --86 + j*(-13) -160 + j*(75) -199 + j*(-272) --233 + j*(-331) --342 + j*(107) -18 + j*(229) -87 + j*(-29) --98 + j*(6) -40 + j*(168) -213 + j*(-25) -25 + j*(-207) --131 + j*(-75) --62 + j*(12) --69 + j*(-28) --123 + j*(47) --41 + j*(129) -35 + j*(94) -56 + j*(64) -83 + j*(13) -10 + j*(-50) --74 + j*(51) -56 + j*(165) -204 + j*(49) -142 + j*(-91) -78 + j*(-69) -125 + j*(-101) -64 + j*(-228) --124 + j*(-233) --235 + j*(-74) --181 + j*(107) --5 + j*(154) -80 + j*(28) --16 + j*(-20) -17 + j*(107) -236 + j*(8) -134 + j*(-330) --291 + j*(-291) --337 + j*(137) -24 + j*(231) -107 + j*(-56) --137 + j*(-117) --220 + j*(99) --74 + j*(236) -87 + j*(215) -190 + j*(102) -170 + j*(-55) -44 + j*(-113) --37 + j*(-57) --55 + j*(-3) --64 + j*(71) -32 + j*(159) -192 + j*(98) -202 + j*(-74) -95 + j*(-137) -58 + j*(-116) -57 + j*(-165) --45 + j*(-228) --190 + j*(-177) --257 + j*(-37) --233 + j*(117) --110 + j*(246) -111 + j*(260) -280 + j*(59) -185 + j*(-203) --71 + j*(-223) --153 + j*(-43) --52 + j*(22) --49 + j*(-45) --122 + j*(-13) --112 + j*(59) --109 + j*(77) --118 + j*(186) -57 + j*(296) -267 + j*(158) -236 + j*(-60) -112 + j*(-116) -49 + j*(-120) --46 + j*(-100) --64 + j*(30) -73 + j*(61) -98 + j*(-70) --2 + j*(-81) -14 + j*(-40) --16 + j*(-98) --130 + j*(4) -43 + j*(180) -282 + j*(-47) -43 + j*(-334) --238 + j*(-124) --54 + j*(81) -45 + j*(-129) --231 + j*(-156) --253 + j*(165) -40 + j*(216) -103 + j*(1) --19 + j*(-45) --43 + j*(-1) --65 + j*(13) --57 + j*(88) -45 + j*(73) -1 + j*(-36) --126 + j*(59) --6 + j*(226) -196 + j*(142) -196 + j*(-37) -100 + j*(-117) --24 + j*(-124) --115 + j*(30) -78 + j*(194) -328 + j*(-31) -119 + j*(-364) --248 + j*(-228) --198 + j*(104) -54 + j*(115) -112 + j*(-59) -21 + j*(-175) --156 + j*(-185) --276 + j*(3) --127 + j*(174) --3 + j*(57) --167 + j*(33) --131 + j*(307) -233 + j*(283) -233 + j*(-86) --93 + j*(-55) -10 + j*(262) -358 + j*(125) -259 + j*(-226) --8 + j*(-181) -48 + j*(-40) -110 + j*(-176) --99 + j*(-247) --218 + j*(-33) --54 + j*(109) -65 + j*(-14) --57 + j*(-100) --139 + j*(45) -28 + j*(158) -182 + j*(0) -69 + j*(-180) --88 + j*(-124) --69 + j*(-43) --74 + j*(-78) --165 + j*(-21) --103 + j*(114) -45 + j*(63) --7 + j*(-81) --170 + j*(-40) --177 + j*(142) --13 + j*(234) -148 + j*(132) -103 + j*(-50) --79 + j*(-21) --26 + j*(179) -214 + j*(95) -111 + j*(-183) --202 + j*(-62) --65 + j*(286) -315 + j*(166) -247 + j*(-214) --81 + j*(-214) --130 + j*(21) -3 + j*(99) -97 + j*(65) -159 + j*(-36) -64 + j*(-176) --128 + j*(-100) --64 + j*(124) -179 + j*(76) -174 + j*(-169) --23 + j*(-226) --122 + j*(-134) --151 + j*(-48) --122 + j*(69) -34 + j*(99) -103 + j*(-63) --43 + j*(-161) --153 + j*(-62) --126 + j*(22) --119 + j*(59) --62 + j*(153) -116 + j*(122) -127 + j*(-105) --116 + j*(-155) --199 + j*(83) -21 + j*(189) -140 + j*(-9) --33 + j*(-146) --199 + j*(-18) --157 + j*(160) --21 + j*(222) -100 + j*(185) -158 + j*(81) -110 + j*(-5) -48 + j*(25) -108 + j*(71) -187 + j*(-6) -154 + j*(-117) -86 + j*(-159) -15 + j*(-206) --144 + j*(-207) --269 + j*(-13) --130 + j*(208) -117 + j*(156) -132 + j*(-68) --62 + j*(-125) --164 + j*(41) --47 + j*(194) -119 + j*(163) -163 + j*(57) -165 + j*(20) -226 + j*(-57) -159 + j*(-233) --67 + j*(-223) --69 + j*(-4) -162 + j*(-57) -66 + j*(-364) --327 + j*(-300) --351 + j*(98) --35 + j*(180) -35 + j*(-36) --113 + j*(-70) --138 + j*(25) --122 + j*(54) --122 + j*(134) -18 + j*(202) -151 + j*(71) -77 + j*(-88) --50 + j*(-88) --115 + j*(-35) --170 + j*(60) --103 + j*(218) -100 + j*(221) -163 + j*(52) -70 + j*(0) -94 + j*(52) -177 + j*(-44) -76 + j*(-206) --129 + j*(-180) --207 + j*(-13) --145 + j*(124) --36 + j*(175) -72 + j*(143) -110 + j*(42) -35 + j*(-27) --54 + j*(42) -8 + j*(174) -184 + j*(151) -238 + j*(-20) -127 + j*(-120) -41 + j*(-89) -18 + j*(-49) -14 + j*(13) -120 + j*(69) -255 + j*(-63) -156 + j*(-270) --48 + j*(-243) --50 + j*(-122) --13 + j*(-175) --153 + j*(-200) --223 + j*(-23) --74 + j*(87) -52 + j*(-10) -15 + j*(-144) --121 + j*(-197) --276 + j*(-108) --284 + j*(95) --121 + j*(185) --32 + j*(103) --72 + j*(75) --62 + j*(121) --23 + j*(132) -16 + j*(161) -151 + j*(142) -204 + j*(-68) --15 + j*(-202) --190 + j*(-33) --98 + j*(127) --8 + j*(94) --21 + j*(100) -47 + j*(135) -111 + j*(59) -66 + j*(-3) -42 + j*(13) -32 + j*(-7) --28 + j*(33) -42 + j*(144) -214 + j*(71) -183 + j*(-139) --11 + j*(-169) --77 + j*(-37) --13 + j*(28) -28 + j*(4) -6 + j*(-13) --9 + j*(39) -87 + j*(86) -190 + j*(-39) -71 + j*(-185) --72 + j*(-78) -59 + j*(27) -148 + j*(-169) --95 + j*(-299) --284 + j*(-90) --183 + j*(114) --41 + j*(128) -42 + j*(76) -41 + j*(-37) --104 + j*(-27) --61 + j*(190) -254 + j*(127) -204 + j*(-261) --199 + j*(-235) --174 + j*(119) -93 + j*(52) --48 + j*(-120) --139 + j*(107) -165 + j*(136) -159 + j*(-217) --197 + j*(-197) --162 + j*(107) -62 + j*(37) --49 + j*(-124) --175 + j*(-10) --124 + j*(65) --156 + j*(110) --60 + j*(294) -245 + j*(221) -237 + j*(-116) --35 + j*(-135) --19 + j*(35) -81 + j*(-70) --105 + j*(-158) --230 + j*(45) --98 + j*(192) -4 + j*(180) -74 + j*(200) -221 + j*(139) -243 + j*(-57) -95 + j*(-151) --8 + j*(-93) --18 + j*(-30) -0 + j*(6) -32 + j*(16) -68 + j*(11) -120 + j*(-41) -82 + j*(-187) --162 + j*(-208) --276 + j*(105) -57 + j*(322) -353 + j*(23) -128 + j*(-309) --186 + j*(-168) --115 + j*(102) -116 + j*(84) -170 + j*(-120) -5 + j*(-276) --236 + j*(-190) --244 + j*(74) --15 + j*(129) -18 + j*(-59) --169 + j*(-57) --166 + j*(146) -8 + j*(187) -89 + j*(97) -104 + j*(8) -26 + j*(-96) --151 + j*(-27) --93 + j*(222) -204 + j*(211) -271 + j*(-60) -118 + j*(-177) -35 + j*(-197) --118 + j*(-234) --296 + j*(-45) --152 + j*(199) -51 + j*(112) --34 + j*(23) --15 + j*(175) -233 + j*(110) -190 + j*(-203) --110 + j*(-227) --203 + j*(-18) --148 + j*(100) --77 + j*(214) -154 + j*(251) -313 + j*(-6) -112 + j*(-228) --91 + j*(-103) -2 + j*(36) -103 + j*(-71) --13 + j*(-194) --187 + j*(-126) --211 + j*(74) --35 + j*(177) -103 + j*(34) --38 + j*(-107) --194 + j*(48) --54 + j*(236) -139 + j*(153) -111 + j*(17) -49 + j*(28) -78 + j*(55) -118 + j*(41) -170 + j*(-4) -170 + j*(-122) -45 + j*(-183) --30 + j*(-103) -19 + j*(-76) --4 + j*(-136) --82 + j*(-109) --69 + j*(-55) --71 + j*(-72) --119 + j*(-47) --114 + j*(8) --107 + j*(29) --91 + j*(101) -47 + j*(107) -65 + j*(-80) --173 + j*(-102) --209 + j*(184) -93 + j*(252) -185 + j*(-21) --38 + j*(-115) --121 + j*(50) --29 + j*(117) --6 + j*(107) -30 + j*(156) -132 + j*(152) -189 + j*(82) -221 + j*(23) -244 + j*(-66) -218 + j*(-163) -179 + j*(-264) -26 + j*(-409) --295 + j*(-341) --363 + j*(37) --18 + j*(168) -91 + j*(-151) --255 + j*(-233) --349 + j*(125) --42 + j*(233) -11 + j*(0) --204 + j*(31) --136 + j*(288) -141 + j*(272) -200 + j*(45) -67 + j*(-45) --9 + j*(32) -59 + j*(119) -215 + j*(54) -209 + j*(-194) --94 + j*(-302) --320 + j*(-16) --112 + j*(284) -194 + j*(171) -148 + j*(-88) --57 + j*(-61) --19 + j*(124) -183 + j*(101) -230 + j*(-124) -29 + j*(-272) --207 + j*(-153) --192 + j*(122) -68 + j*(192) -184 + j*(-30) -1 + j*(-141) --74 + j*(33) -127 + j*(67) -157 + j*(-180) --114 + j*(-251) --228 + j*(-17) --82 + j*(104) --14 + j*(49) --8 + j*(66) -86 + j*(42) -71 + j*(-99) --79 + j*(-98) --80 + j*(25) --6 + j*(4) --71 + j*(-25) --71 + j*(88) -77 + j*(71) -49 + j*(-103) --151 + j*(-70) --147 + j*(149) -59 + j*(213) -199 + j*(84) -207 + j*(-97) -67 + j*(-251) --182 + j*(-228) --293 + j*(14) --147 + j*(204) -23 + j*(180) -74 + j*(98) -80 + j*(47) -62 + j*(-4) -2 + j*(-7) --12 + j*(57) -57 + j*(87) -107 + j*(38) -102 + j*(0) -119 + j*(-10) -156 + j*(-88) -71 + j*(-206) --96 + j*(-164) --83 + j*(-8) -54 + j*(-48) --49 + j*(-215) --287 + j*(-91) --204 + j*(205) -94 + j*(183) -115 + j*(-76) --100 + j*(-132) --210 + j*(28) --159 + j*(198) -22 + j*(296) -242 + j*(185) -238 + j*(-55) -69 + j*(-94) -85 + j*(-11) -148 + j*(-138) --55 + j*(-249) --222 + j*(-41) --63 + j*(134) -74 + j*(28) -4 + j*(-62) --53 + j*(-33) --95 + j*(4) --113 + j*(147) -127 + j*(271) -388 + j*(-3) -170 + j*(-368) --207 + j*(-255) --165 + j*(28) --20 + j*(-34) --176 + j*(-87) --212 + j*(161) -56 + j*(214) -88 + j*(-25) --130 + j*(20) --13 + j*(269) -270 + j*(145) -179 + j*(-109) -32 + j*(-13) -214 + j*(32) -240 + j*(-249) --54 + j*(-318) --115 + j*(-124) --49 + j*(-179) --281 + j*(-192) --308 + j*(177) -122 + j*(210) -110 + j*(-257) --413 + j*(-193) --341 + j*(371) -194 + j*(319) -129 + j*(-114) --196 + j*(16) -9 + j*(273) -226 + j*(30) --14 + j*(-144) --143 + j*(71) -37 + j*(160) -98 + j*(29) -11 + j*(-23) --62 + j*(30) --59 + j*(172) -170 + j*(260) -374 + j*(-22) -91 + j*(-315) --235 + j*(-52) -17 + j*(264) -308 + j*(32) -112 + j*(-209) --40 + j*(-46) -129 + j*(11) -146 + j*(-182) --29 + j*(-237) --134 + j*(-165) --228 + j*(-64) --201 + j*(183) -124 + j*(269) -307 + j*(-57) -36 + j*(-274) --158 + j*(-65) -25 + j*(76) -141 + j*(-103) --4 + j*(-233) --125 + j*(-177) --166 + j*(-139) --263 + j*(-87) --305 + j*(98) --144 + j*(253) -52 + j*(184) -46 + j*(33) --37 + j*(44) -24 + j*(87) -57 + j*(-37) --132 + j*(-75) --199 + j*(168) -64 + j*(276) -189 + j*(35) --25 + j*(-61) --81 + j*(156) -144 + j*(209) -223 + j*(22) -127 + j*(-48) -130 + j*(-33) -136 + j*(-127) -8 + j*(-185) --102 + j*(-104) --106 + j*(10) --30 + j*(91) -103 + j*(66) -124 + j*(-93) --32 + j*(-141) --78 + j*(-13) -25 + j*(-13) --52 + j*(-115) --190 + j*(29) --10 + j*(219) -214 + j*(38) -43 + j*(-186) --152 + j*(-14) -47 + j*(155) -214 + j*(-83) --40 + j*(-281) --275 + j*(-59) --132 + j*(180) -62 + j*(122) -66 + j*(18) -66 + j*(-15) -33 + j*(-124) --178 + j*(-131) --274 + j*(151) -3 + j*(363) -296 + j*(180) -255 + j*(-107) -62 + j*(-172) --33 + j*(-97) --42 + j*(-28) --8 + j*(23) -67 + j*(13) -92 + j*(-84) --1 + j*(-163) --136 + j*(-114) --154 + j*(33) --37 + j*(105) -46 + j*(37) -23 + j*(-28) --10 + j*(-42) --65 + j*(-58) --161 + j*(40) --48 + j*(238) -242 + j*(153) -208 + j*(-176) --96 + j*(-171) --71 + j*(79) -141 + j*(0) -22 + j*(-195) --145 + j*(-69) --23 + j*(32) -1 + j*(-106) --158 + j*(-91) --144 + j*(37) --114 + j*(6) --225 + j*(88) --99 + j*(313) -187 + j*(224) -156 + j*(-27) -6 + j*(-21) -26 + j*(18) --44 + j*(-21) --110 + j*(156) -166 + j*(279) -373 + j*(-39) -102 + j*(-322) --210 + j*(-171) --206 + j*(98) --38 + j*(230) -175 + j*(190) -238 + j*(-39) -24 + j*(-137) --42 + j*(72) -193 + j*(92) -178 + j*(-170) --78 + j*(-119) -30 + j*(127) -289 + j*(-23) -171 + j*(-293) --29 + j*(-264) --54 + j*(-238) --212 + j*(-272) --380 + j*(-33) --190 + j*(227) -57 + j*(135) -23 + j*(-16) --23 + j*(14) -38 + j*(-11) --19 + j*(-117) --170 + j*(-73) --187 + j*(109) --20 + j*(211) -161 + j*(103) -127 + j*(-109) --69 + j*(-141) --123 + j*(8) --30 + j*(41) --50 + j*(-23) --117 + j*(51) --20 + j*(134) -69 + j*(46) --4 + j*(-28) --60 + j*(30) --26 + j*(81) -18 + j*(88) -84 + j*(67) -106 + j*(-46) --32 + j*(-121) --155 + j*(11) --52 + j*(162) -104 + j*(91) -49 + j*(-57) --107 + j*(-10) --84 + j*(162) -78 + j*(184) -108 + j*(79) -66 + j*(119) -233 + j*(180) -402 + j*(-80) -151 + j*(-373) --197 + j*(-202) --103 + j*(110) -122 + j*(50) -57 + j*(-78) -13 + j*(30) -183 + j*(25) -190 + j*(-180) -16 + j*(-221) --12 + j*(-131) -28 + j*(-171) --58 + j*(-234) --159 + j*(-191) --208 + j*(-126) --233 + j*(-35) --175 + j*(46) --124 + j*(7) --218 + j*(2) --249 + j*(175) --74 + j*(280) -54 + j*(189) -38 + j*(134) -87 + j*(160) -177 + j*(76) -134 + j*(-44) -55 + j*(-45) -66 + j*(-36) -42 + j*(-107) --86 + j*(-110) --147 + j*(40) --18 + j*(158) -138 + j*(78) -116 + j*(-87) --26 + j*(-118) --91 + j*(-23) --45 + j*(52) -23 + j*(49) -59 + j*(-13) -6 + j*(-88) --102 + j*(-58) --103 + j*(64) -0 + j*(80) -0 + j*(1) --79 + j*(38) --22 + j*(141) -101 + j*(96) -76 + j*(-18) --18 + j*(6) -22 + j*(97) -136 + j*(53) -112 + j*(-92) --50 + j*(-98) --86 + j*(70) -83 + j*(131) -158 + j*(-28) -12 + j*(-99) --45 + j*(52) -128 + j*(119) -250 + j*(-48) -161 + j*(-238) --41 + j*(-281) --210 + j*(-143) --170 + j*(83) -44 + j*(117) -103 + j*(-55) --17 + j*(-90) -6 + j*(-11) -67 + j*(-115) --100 + j*(-185) --186 + j*(7) -6 + j*(85) -59 + j*(-106) --128 + j*(-150) --174 + j*(-2) --106 + j*(23) --146 + j*(30) --115 + j*(137) -16 + j*(115) --12 + j*(10) --88 + j*(73) -11 + j*(140) -76 + j*(25) --41 + j*(-23) --69 + j*(100) -61 + j*(120) -73 + j*(-14) --76 + j*(-17) --76 + j*(166) -146 + j*(190) -203 + j*(-59) --65 + j*(-141) --179 + j*(158) -127 + j*(331) -366 + j*(92) -271 + j*(-130) -192 + j*(-168) -129 + j*(-303) --170 + j*(-330) --313 + j*(18) -4 + j*(231) -230 + j*(-30) -35 + j*(-240) --133 + j*(-135) --115 + j*(-52) --153 + j*(-35) --172 + j*(101) --16 + j*(192) -129 + j*(86) -98 + j*(-69) --40 + j*(-105) --125 + j*(18) --9 + j*(138) -136 + j*(25) -25 + j*(-136) --140 + j*(-26) --40 + j*(128) -86 + j*(42) -8 + j*(-37) --24 + j*(43) -59 + j*(53) -67 + j*(-8) -61 + j*(-6) -91 + j*(-59) -16 + j*(-127) --57 + j*(-59) -2 + j*(-24) --6 + j*(-105) --116 + j*(-82) --112 + j*(23) --62 + j*(28) --76 + j*(44) --19 + j*(91) -38 + j*(19) --56 + j*(-11) --56 + j*(129) -135 + j*(124) -157 + j*(-80) -3 + j*(-127) --21 + j*(-65) --49 + j*(-135) --255 + j*(-85) --267 + j*(240) -88 + j*(366) -314 + j*(74) -134 + j*(-172) --48 + j*(-84) -16 + j*(-5) -13 + j*(-124) --199 + j*(-104) --243 + j*(177) -21 + j*(323) -231 + j*(174) -241 + j*(6) -211 + j*(-120) -67 + j*(-256) --177 + j*(-171) --163 + j*(88) -32 + j*(101) -6 + j*(3) --6 + j*(133) -254 + j*(110) -267 + j*(-250) --100 + j*(-334) --221 + j*(-70) --113 + j*(-4) --188 + j*(12) --129 + j*(237) -175 + j*(192) -129 + j*(-105) --121 + j*(4) -83 + j*(243) -358 + j*(-13) -136 + j*(-320) --134 + j*(-193) --85 + j*(-28) --25 + j*(-49) --39 + j*(-59) --42 + j*(-81) --126 + j*(-83) --144 + j*(44) --16 + j*(53) --59 + j*(-66) --182 + j*(48) --15 + j*(173) -83 + j*(-40) --190 + j*(-96) --234 + j*(235) -103 + j*(293) -141 + j*(22) --61 + j*(75) -105 + j*(276) -367 + j*(68) -211 + j*(-231) --35 + j*(-161) -0 + j*(-14) -74 + j*(-76) --12 + j*(-136) --82 + j*(-64) --36 + j*(-12) --21 + j*(-69) --129 + j*(-76) --170 + j*(76) --22 + j*(163) -64 + j*(42) --47 + j*(8) --32 + j*(148) -131 + j*(115) -85 + j*(-23) -4 + j*(89) -236 + j*(157) -371 + j*(-161) -77 + j*(-395) --167 + j*(-233) --142 + j*(-103) --190 + j*(-85) --221 + j*(99) --4 + j*(197) -113 + j*(18) --13 + j*(-54) --8 + j*(36) -69 + j*(-48) --64 + j*(-131) --150 + j*(8) --42 + j*(59) --83 + j*(-22) --187 + j*(132) -33 + j*(313) -291 + j*(114) -173 + j*(-157) --25 + j*(-118) --11 + j*(-26) --4 + j*(-68) --82 + j*(-47) --72 + j*(32) --42 + j*(31) --70 + j*(67) -2 + j*(145) -115 + j*(83) -69 + j*(-19) -2 + j*(51) -117 + j*(122) -245 + j*(2) -214 + j*(-159) -125 + j*(-253) --7 + j*(-340) --247 + j*(-320) --415 + j*(-74) --314 + j*(210) --62 + j*(283) -95 + j*(155) -68 + j*(13) --33 + j*(16) --16 + j*(117) -112 + j*(99) -112 + j*(-35) -4 + j*(-37) -42 + j*(50) -138 + j*(-35) -48 + j*(-168) --95 + j*(-132) --135 + j*(-46) --175 + j*(45) --99 + j*(234) -212 + j*(230) -308 + j*(-136) --42 + j*(-317) --255 + j*(-39) --71 + j*(141) -24 + j*(26) --61 + j*(32) -14 + j*(115) -88 + j*(12) --23 + j*(-21) -12 + j*(112) -178 + j*(14) -47 + j*(-193) --189 + j*(-53) --62 + j*(185) -148 + j*(84) -74 + j*(-69) --12 + j*(-4) -55 + j*(35) -66 + j*(-12) -81 + j*(13) -192 + j*(-59) -122 + j*(-283) --159 + j*(-285) --238 + j*(-45) --95 + j*(30) --93 + j*(-46) --166 + j*(18) --97 + j*(98) --63 + j*(34) --175 + j*(78) --115 + j*(289) -161 + j*(317) -301 + j*(96) -231 + j*(-69) -163 + j*(-127) -91 + j*(-209) --72 + j*(-214) --153 + j*(-78) --91 + j*(0) --83 + j*(-28) --144 + j*(37) --59 + j*(159) -102 + j*(96) -62 + j*(-69) --101 + j*(-29) --47 + j*(142) -145 + j*(75) -66 + j*(-145) --194 + j*(-59) --121 + j*(255) -226 + j*(237) -284 + j*(-82) -60 + j*(-177) -6 + j*(-68) -46 + j*(-112) --89 + j*(-147) --141 + j*(33) -42 + j*(86) -74 + j*(-95) --98 + j*(-101) --79 + j*(47) -28 + j*(-16) --104 + j*(-104) --210 + j*(83) --21 + j*(232) -139 + j*(103) -92 + j*(-8) -67 + j*(-16) -40 + j*(-74) --71 + j*(-34) -2 + j*(122) -231 + j*(6) -110 + j*(-317) --290 + j*(-269) --358 + j*(111) --109 + j*(267) -21 + j*(192) -65 + j*(185) -185 + j*(136) -192 + j*(-16) -103 + j*(-41) -150 + j*(-35) -134 + j*(-185) --76 + j*(-198) --94 + j*(1) -70 + j*(-44) --75 + j*(-212) --285 + j*(13) --35 + j*(257) -196 + j*(19) --34 + j*(-148) --113 + j*(96) -163 + j*(103) -129 + j*(-198) --148 + j*(-154) --99 + j*(44) --8 + j*(-47) --171 + j*(-51) --137 + j*(169) -82 + j*(134) -39 + j*(-27) --40 + j*(47) -66 + j*(49) -6 + j*(-69) --103 + j*(54) -69 + j*(132) -98 + j*(-70) --124 + j*(-29) --10 + j*(222) -260 + j*(67) -114 + j*(-181) --49 + j*(-58) -71 + j*(-25) --18 + j*(-165) --169 + j*(13) -81 + j*(142) -180 + j*(-171) --167 + j*(-261) --250 + j*(37) --76 + j*(62) --204 + j*(18) --202 + j*(334) -235 + j*(380) -347 + j*(-47) -23 + j*(-152) -3 + j*(66) -168 + j*(-11) -37 + j*(-153) --72 + j*(-21) -45 + j*(47) -83 + j*(-41) -49 + j*(-69) -35 + j*(-114) --78 + j*(-126) --99 + j*(24) -77 + j*(13) -19 + j*(-216) --276 + j*(-156) --284 + j*(150) --77 + j*(244) -25 + j*(216) -167 + j*(210) -296 + j*(-6) -105 + j*(-216) --93 + j*(-66) -57 + j*(64) -146 + j*(-127) --79 + j*(-224) --211 + j*(-19) --73 + j*(138) -80 + j*(81) -96 + j*(-46) -1 + j*(-110) --70 + j*(-42) -5 + j*(-4) -1 + j*(-139) --228 + j*(-139) --295 + j*(160) --11 + j*(317) -194 + j*(139) -155 + j*(-28) -108 + j*(-105) --11 + j*(-213) --255 + j*(-135) --271 + j*(165) --18 + j*(264) -84 + j*(119) -25 + j*(99) -105 + j*(161) -235 + j*(39) -151 + j*(-148) --40 + j*(-140) --90 + j*(16) -25 + j*(94) -120 + j*(14) -75 + j*(-83) -5 + j*(-74) -2 + j*(-60) --56 + j*(-86) --141 + j*(25) --11 + j*(178) -184 + j*(57) -73 + j*(-150) --120 + j*(-24) -37 + j*(170) -266 + j*(-8) -126 + j*(-279) --144 + j*(-231) --191 + j*(-41) --134 + j*(50) --66 + j*(119) -76 + j*(112) -122 + j*(-46) --18 + j*(-110) --66 + j*(10) -49 + j*(23) -34 + j*(-105) --104 + j*(-74) --68 + j*(72) -86 + j*(34) -71 + j*(-132) --91 + j*(-177) --204 + j*(-71) --194 + j*(69) --88 + j*(142) -6 + j*(93) --11 + j*(27) --46 + j*(41) --32 + j*(51) --63 + j*(48) --66 + j*(142) -88 + j*(167) -131 + j*(-28) --103 + j*(-74) --167 + j*(211) -144 + j*(334) -329 + j*(72) -173 + j*(-104) -86 + j*(-20) -187 + j*(-28) -176 + j*(-183) -21 + j*(-251) --116 + j*(-192) --187 + j*(-69) --146 + j*(75) --13 + j*(116) -58 + j*(46) -50 + j*(-4) -40 + j*(-40) --24 + j*(-63) --74 + j*(33) -59 + j*(116) -192 + j*(-36) -55 + j*(-223) --163 + j*(-145) --164 + j*(65) --1 + j*(142) -137 + j*(43) -119 + j*(-133) --65 + j*(-199) --193 + j*(-47) --95 + j*(98) -14 + j*(49) --11 + j*(-2) --1 + j*(20) -31 + j*(-43) --79 + j*(-95) --156 + j*(33) --37 + j*(119) -28 + j*(18) --74 + j*(-13) --95 + j*(91) --21 + j*(122) --11 + j*(119) -47 + j*(191) -222 + j*(151) -265 + j*(-71) -82 + j*(-185) --40 + j*(-66) -66 + j*(24) -174 + j*(-113) -35 + j*(-313) --267 + j*(-271) --388 + j*(52) --160 + j*(308) -133 + j*(223) -158 + j*(-12) -13 + j*(-76) --36 + j*(-8) --13 + j*(6) --27 + j*(-4) --44 + j*(18) --49 + j*(32) --75 + j*(81) --13 + j*(182) -148 + j*(168) -200 + j*(19) -131 + j*(-46) -139 + j*(-54) -121 + j*(-175) --78 + j*(-204) --154 + j*(7) -37 + j*(87) -86 + j*(-81) --64 + j*(-85) --6 + j*(43) -111 + j*(-93) --103 + j*(-233) --294 + j*(11) --91 + j*(235) -106 + j*(117) -64 + j*(27) -110 + j*(53) -191 + j*(-95) -31 + j*(-250) --144 + j*(-170) --157 + j*(-76) --209 + j*(-36) --236 + j*(128) --69 + j*(251) -84 + j*(177) -125 + j*(95) -177 + j*(-8) -71 + j*(-192) --204 + j*(-117) --164 + j*(200) -153 + j*(187) -148 + j*(-98) --88 + j*(-79) --40 + j*(113) -110 + j*(35) -11 + j*(-76) --71 + j*(46) -70 + j*(124) -175 + j*(-5) -114 + j*(-146) --22 + j*(-192) --167 + j*(-117) --182 + j*(71) --16 + j*(154) -81 + j*(30) --27 + j*(-45) --94 + j*(90) -71 + j*(202) -274 + j*(52) -215 + j*(-234) --93 + j*(-301) --268 + j*(-52) --110 + j*(161) -73 + j*(81) -32 + j*(-45) --45 + j*(-16) --29 + j*(23) --31 + j*(35) -9 + j*(85) -100 + j*(33) -43 + j*(-78) --61 + j*(1) -64 + j*(94) -168 + j*(-78) --13 + j*(-205) --144 + j*(-61) --56 + j*(13) --86 + j*(-42) --156 + j*(94) -42 + j*(208) -191 + j*(-6) --13 + j*(-153) --127 + j*(37) -59 + j*(109) -88 + j*(-75) --93 + j*(-64) --45 + j*(118) -148 + j*(40) -61 + j*(-171) --164 + j*(-104) --133 + j*(106) -27 + j*(103) -9 + j*(1) --65 + j*(74) -59 + j*(178) -222 + j*(57) -158 + j*(-132) -12 + j*(-125) -33 + j*(-59) -55 + j*(-160) --129 + j*(-214) --256 + j*(-8) --85 + j*(175) -112 + j*(47) -15 + j*(-156) --210 + j*(-97) --221 + j*(140) --15 + j*(230) -112 + j*(87) -8 + j*(-23) --72 + j*(98) -100 + j*(187) -235 + j*(-24) -18 + j*(-221) --236 + j*(-31) --109 + j*(274) -211 + j*(248) -299 + j*(-25) -122 + j*(-179) --27 + j*(-86) -56 + j*(40) -208 + j*(-78) -81 + j*(-318) --235 + j*(-260) --277 + j*(49) --59 + j*(149) -13 + j*(44) --18 + j*(52) -71 + j*(60) -81 + j*(-71) --65 + j*(-76) --45 + j*(76) -122 + j*(35) -91 + j*(-156) --100 + j*(-170) --175 + j*(-18) --83 + j*(103) -70 + j*(66) -72 + j*(-126) --162 + j*(-174) --268 + j*(81) --34 + j*(223) -95 + j*(27) --81 + j*(-58) --129 + j*(103) --10 + j*(121) --62 + j*(67) --89 + j*(242) -182 + j*(332) -387 + j*(71) -248 + j*(-204) --4 + j*(-214) --124 + j*(-41) --28 + j*(148) -207 + j*(115) -240 + j*(-131) -43 + j*(-199) -14 + j*(-80) -99 + j*(-156) --59 + j*(-278) --228 + j*(-122) --134 + j*(25) --71 + j*(-31) --134 + j*(-13) --91 + j*(50) --78 + j*(2) --161 + j*(66) --52 + j*(206) -125 + j*(95) -28 + j*(-72) --110 + j*(14) --52 + j*(128) -25 + j*(127) -94 + j*(114) -146 + j*(-5) --8 + j*(-91) --98 + j*(117) -173 + j*(220) -301 + j*(-74) -52 + j*(-197) -16 + j*(-13) -180 + j*(-112) --13 + j*(-313) --245 + j*(-104) --64 + j*(89) -49 + j*(-84) --145 + j*(-141) --194 + j*(45) --72 + j*(105) --32 + j*(76) -17 + j*(74) -37 + j*(-18) --81 + j*(-42) --104 + j*(80) --23 + j*(100) --51 + j*(107) -42 + j*(243) -305 + j*(128) -233 + j*(-210) --93 + j*(-184) --76 + j*(74) -112 + j*(35) -50 + j*(-95) --22 + j*(-21) -63 + j*(-1) -66 + j*(-93) -1 + j*(-117) --45 + j*(-119) --119 + j*(-73) --69 + j*(36) -47 + j*(-61) --136 + j*(-212) --364 + j*(19) --169 + j*(305) -76 + j*(196) -14 + j*(92) -61 + j*(190) -235 + j*(61) -98 + j*(-155) --96 + j*(-29) -35 + j*(119) -154 + j*(-23) -37 + j*(-140) --79 + j*(-98) --150 + j*(-16) --151 + j*(161) -73 + j*(278) -285 + j*(93) -202 + j*(-139) -32 + j*(-159) --49 + j*(-87) --57 + j*(21) -84 + j*(85) -197 + j*(-92) -2 + j*(-245) --152 + j*(-64) -23 + j*(43) -71 + j*(-156) --158 + j*(-175) --177 + j*(49) -2 + j*(60) --1 + j*(-68) --82 + j*(-66) --103 + j*(-56) --190 + j*(-33) --222 + j*(119) --102 + j*(221) --3 + j*(219) -112 + j*(226) -266 + j*(72) -149 + j*(-171) --91 + j*(-102) --21 + j*(69) -61 + j*(-51) --136 + j*(-63) --110 + j*(204) -182 + j*(163) -125 + j*(-103) --85 + j*(6) -95 + j*(177) -266 + j*(-32) -110 + j*(-194) -34 + j*(-147) -1 + j*(-245) --282 + j*(-225) --354 + j*(159) -15 + j*(309) -162 + j*(33) --21 + j*(-33) -23 + j*(92) -115 + j*(-56) --123 + j*(-117) --177 + j*(212) -219 + j*(306) -383 + j*(-83) -90 + j*(-290) --67 + j*(-128) -14 + j*(-94) --74 + j*(-182) --212 + j*(-44) --86 + j*(112) -40 + j*(11) --71 + j*(-66) --117 + j*(74) -45 + j*(103) -53 + j*(-76) --162 + j*(-62) --153 + j*(212) -172 + j*(257) -296 + j*(-73) -11 + j*(-260) --197 + j*(-38) --28 + j*(155) -134 + j*(14) -11 + j*(-101) --45 + j*(18) -98 + j*(8) -37 + j*(-184) --190 + j*(-105) --107 + j*(119) -73 + j*(1) --116 + j*(-134) --236 + j*(137) -83 + j*(258) -188 + j*(-74) --141 + j*(-133) --141 + j*(196) -178 + j*(144) -77 + j*(-153) --197 + j*(-9) --36 + j*(248) -184 + j*(119) -115 + j*(-14) -110 + j*(16) -146 + j*(-99) --31 + j*(-158) --87 + j*(29) -91 + j*(44) -52 + j*(-133) --122 + j*(-55) --30 + j*(98) -74 + j*(4) --31 + j*(-33) --4 + j*(100) -165 + j*(47) -131 + j*(-136) --23 + j*(-144) --62 + j*(-45) --7 + j*(18) -103 + j*(-16) -102 + j*(-202) --154 + j*(-264) --269 + j*(8) --14 + j*(118) -39 + j*(-144) --268 + j*(-148) --272 + j*(185) -19 + j*(200) --1 + j*(0) --125 + j*(96) -30 + j*(173) -55 + j*(-4) --146 + j*(56) --10 + j*(319) -322 + j*(182) -257 + j*(-162) --13 + j*(-180) --65 + j*(-35) --40 + j*(-1) --58 + j*(54) -21 + j*(128) -138 + j*(82) -168 + j*(-33) -116 + j*(-145) --39 + j*(-184) --156 + j*(-38) --47 + j*(105) -68 + j*(25) --13 + j*(-14) -35 + j*(111) -247 + j*(3) -142 + j*(-295) --182 + j*(-240) --173 + j*(28) -1 + j*(16) --51 + j*(-80) --89 + j*(-8) --27 + j*(-38) --166 + j*(-100) --269 + j*(147) -30 + j*(319) -247 + j*(24) --16 + j*(-187) --190 + j*(47) -23 + j*(173) -90 + j*(-25) --108 + j*(-33) --93 + j*(188) -130 + j*(202) -206 + j*(45) -183 + j*(-49) -161 + j*(-170) --33 + j*(-283) --267 + j*(-117) --189 + j*(159) -41 + j*(152) -41 + j*(3) --54 + j*(52) -41 + j*(136) -129 + j*(34) -35 + j*(-28) -20 + j*(85) -183 + j*(83) -219 + j*(-107) -69 + j*(-186) -3 + j*(-112) -37 + j*(-106) -4 + j*(-153) --51 + j*(-147) --91 + j*(-144) --175 + j*(-95) --158 + j*(46) --6 + j*(42) --35 + j*(-116) --227 + j*(-52) --151 + j*(165) -64 + j*(83) --52 + j*(-116) --252 + j*(39) --90 + j*(250) -103 + j*(104) --49 + j*(-39) --174 + j*(150) -37 + j*(317) -267 + j*(153) -196 + j*(-101) --31 + j*(-114) --81 + j*(76) -90 + j*(135) -138 + j*(-33) --36 + j*(-49) --8 + j*(163) -263 + j*(107) -215 + j*(-211) --100 + j*(-178) --57 + j*(99) -180 + j*(23) -81 + j*(-173) --51 + j*(-57) -98 + j*(-8) -91 + j*(-219) --158 + j*(-207) --163 + j*(16) --11 + j*(6) --74 + j*(-83) --141 + j*(24) --35 + j*(77) --21 + j*(10) --57 + j*(75) -102 + j*(112) -183 + j*(-119) --65 + j*(-275) --282 + j*(-79) --187 + j*(134) --65 + j*(109) --110 + j*(112) --45 + j*(265) -230 + j*(242) -305 + j*(-80) -11 + j*(-239) --171 + j*(6) -42 + j*(171) -181 + j*(-25) -2 + j*(-136) --69 + j*(27) -86 + j*(60) -97 + j*(-74) -13 + j*(-67) -77 + j*(-61) -39 + j*(-223) --218 + j*(-214) --292 + j*(66) --76 + j*(206) -69 + j*(94) -37 + j*(-4) --6 + j*(-4) -2 + j*(16) -38 + j*(-16) --6 + j*(-115) --191 + j*(-93) --235 + j*(159) -21 + j*(279) -175 + j*(70) -17 + j*(-56) --59 + j*(85) -85 + j*(141) -148 + j*(23) -102 + j*(-33) -99 + j*(-64) -39 + j*(-146) --107 + j*(-110) --124 + j*(42) --4 + j*(92) -40 + j*(16) --25 + j*(-8) --51 + j*(77) -54 + j*(139) -168 + j*(46) -113 + j*(-96) --28 + j*(-76) --30 + j*(47) -65 + j*(81) -136 + j*(57) -230 + j*(-17) -228 + j*(-216) -7 + j*(-314) --117 + j*(-148) -7 + j*(-106) --64 + j*(-285) --361 + j*(-161) --272 + j*(223) -129 + j*(195) -146 + j*(-167) --153 + j*(-218) --223 + j*(-16) --141 + j*(37) --156 + j*(42) --127 + j*(127) --32 + j*(117) --32 + j*(57) --54 + j*(74) --26 + j*(62) --93 + j*(35) --158 + j*(176) -22 + j*(332) -271 + j*(197) -228 + j*(-80) --19 + j*(-112) --82 + j*(104) -122 + j*(197) -270 + j*(11) -146 + j*(-187) --59 + j*(-143) --78 + j*(24) -31 + j*(86) -126 + j*(44) -180 + j*(-72) -92 + j*(-243) --170 + j*(-241) --284 + j*(40) --55 + j*(232) -149 + j*(73) -33 + j*(-94) --103 + j*(19) -11 + j*(149) -144 + j*(65) -103 + j*(-41) -56 + j*(-19) -107 + j*(-18) -112 + j*(-110) -12 + j*(-151) --49 + j*(-78) -7 + j*(-21) -65 + j*(-89) --4 + j*(-190) --156 + j*(-168) --218 + j*(-20) --136 + j*(106) --19 + j*(116) -57 + j*(67) -105 + j*(-18) -68 + j*(-156) --119 + j*(-213) --281 + j*(-46) --193 + j*(177) -11 + j*(179) -53 + j*(48) --5 + j*(34) -45 + j*(67) -104 + j*(-28) -14 + j*(-131) --103 + j*(-93) --124 + j*(-23) --140 + j*(9) --147 + j*(88) --59 + j*(136) --20 + j*(49) --163 + j*(47) --187 + j*(293) -126 + j*(425) -369 + j*(152) -197 + j*(-113) --4 + j*(-4) -114 + j*(127) -217 + j*(-8) -110 + j*(-86) -119 + j*(-16) -207 + j*(-158) --29 + j*(-351) --351 + j*(-115) --214 + j*(274) -127 + j*(270) -202 + j*(71) -164 + j*(25) -209 + j*(-23) -180 + j*(-123) -125 + j*(-127) -163 + j*(-175) -66 + j*(-309) --121 + j*(-241) --70 + j*(-93) -13 + j*(-209) --196 + j*(-296) --332 + j*(-61) --144 + j*(71) --88 + j*(-83) --279 + j*(-66) --269 + j*(167) --64 + j*(204) --10 + j*(82) --59 + j*(57) --69 + j*(72) --88 + j*(90) --69 + j*(161) -24 + j*(179) -76 + j*(122) -96 + j*(81) -103 + j*(7) -4 + j*(-44) --62 + j*(68) -54 + j*(134) -95 + j*(29) -12 + j*(61) -164 + j*(158) -338 + j*(-107) -28 + j*(-395) --340 + j*(-124) --163 + j*(250) -137 + j*(159) -92 + j*(-22) -24 + j*(29) -103 + j*(35) -98 + j*(-47) -66 + j*(-48) -89 + j*(-93) --3 + j*(-174) --129 + j*(-92) --98 + j*(28) --38 + j*(42) --7 + j*(63) -78 + j*(34) -50 + j*(-86) --81 + j*(-46) --16 + j*(85) -103 + j*(-8) --16 + j*(-98) --54 + j*(54) -149 + j*(39) -102 + j*(-221) --192 + j*(-181) --167 + j*(105) -78 + j*(81) -42 + j*(-127) --145 + j*(-88) --132 + j*(79) -8 + j*(108) -81 + j*(4) -7 + j*(-110) --141 + j*(-67) --123 + j*(97) -32 + j*(84) --13 + j*(-54) --156 + j*(39) --35 + j*(213) -158 + j*(103) -86 + j*(-72) --36 + j*(-31) --8 + j*(33) -12 + j*(3) --18 + j*(3) --26 + j*(21) --40 + j*(49) --1 + j*(110) -91 + j*(77) -57 + j*(-6) -1 + j*(72) -150 + j*(144) -295 + j*(-41) -176 + j*(-265) --59 + j*(-291) --229 + j*(-135) --201 + j*(130) -114 + j*(213) -281 + j*(-125) --55 + j*(-348) --282 + j*(-45) --9 + j*(112) -31 + j*(-186) --354 + j*(-137) --294 + j*(325) -173 + j*(303) -168 + j*(-91) --138 + j*(-62) --81 + j*(177) -95 + j*(133) -79 + j*(59) -144 + j*(83) -242 + j*(-95) -37 + j*(-299) --247 + j*(-161) --223 + j*(132) -5 + j*(216) -146 + j*(88) -110 + j*(-48) -15 + j*(-57) -13 + j*(1) -62 + j*(-21) -42 + j*(-80) --10 + j*(-93) --57 + j*(-95) --132 + j*(-48) --117 + j*(71) --4 + j*(81) --21 + j*(-1) --98 + j*(76) -10 + j*(199) -175 + j*(142) -238 + j*(12) -245 + j*(-152) -62 + j*(-344) --260 + j*(-221) --199 + j*(131) -117 + j*(80) -23 + j*(-192) --208 + j*(-39) --1 + j*(132) -88 + j*(-134) --250 + j*(-153) --228 + j*(236) -160 + j*(183) -52 + j*(-163) --254 + j*(30) -9 + j*(329) -326 + j*(51) -100 + j*(-272) --187 + j*(-156) --197 + j*(35) --144 + j*(139) --6 + j*(221) -158 + j*(98) -41 + j*(-88) --153 + j*(50) --9 + j*(281) -256 + j*(204) -310 + j*(-22) -224 + j*(-184) -53 + j*(-279) --167 + j*(-194) --196 + j*(51) --12 + j*(165) -132 + j*(88) -176 + j*(-17) -170 + j*(-149) -28 + j*(-263) --156 + j*(-184) --144 + j*(-11) --22 + j*(-8) --47 + j*(-112) --171 + j*(-77) --164 + j*(60) --51 + j*(81) --47 + j*(-8) --152 + j*(21) --140 + j*(176) -28 + j*(229) -139 + j*(130) -151 + j*(42) -165 + j*(-37) -103 + j*(-161) --70 + j*(-179) --158 + j*(-38) --97 + j*(66) --30 + j*(76) -13 + j*(75) -59 + j*(37) -47 + j*(-21) -20 + j*(-23) -34 + j*(-53) --50 + j*(-124) --206 + j*(-18) --139 + j*(218) -118 + j*(235) -202 + j*(41) -112 + j*(-37) -115 + j*(-7) -166 + j*(-97) -34 + j*(-267) --239 + j*(-119) --108 + j*(65) --68 + j*(-85) --296 + j*(1) --157 + j*(327) -224 + j*(201) -135 + j*(-182) --231 + j*(-141) --275 + j*(192) --20 + j*(354) -240 + j*(245) -291 + j*(-37) -54 + j*(-195) --135 + j*(-11) -25 + j*(170) -205 + j*(23) -100 + j*(-162) --71 + j*(-133) --131 + j*(-20) --115 + j*(113) -40 + j*(216) -250 + j*(104) -235 + j*(-154) -15 + j*(-248) --147 + j*(-132) --148 + j*(35) --17 + j*(121) -110 + j*(30) -44 + j*(-112) --106 + j*(-56) --55 + j*(97) -101 + j*(49) -62 + j*(-112) --109 + j*(-88) --120 + j*(91) -51 + j*(150) -152 + j*(11) -57 + j*(-103) --35 + j*(-41) -23 + j*(16) -52 + j*(-61) --41 + j*(-70) --28 + j*(37) -96 + j*(8) -76 + j*(-127) --33 + j*(-134) --47 + j*(-99) --90 + j*(-128) --177 + j*(-52) --112 + j*(59) --25 + j*(-8) --124 + j*(-69) --187 + j*(62) --61 + j*(129) --21 + j*(21) --146 + j*(18) --155 + j*(183) -16 + j*(247) -124 + j*(129) -52 + j*(31) --17 + j*(124) -143 + j*(221) -337 + j*(25) -185 + j*(-251) --93 + j*(-180) --52 + j*(13) -37 + j*(-83) --168 + j*(-117) --214 + j*(187) -127 + j*(282) -261 + j*(-25) -44 + j*(-146) --10 + j*(-31) -24 + j*(-95) --183 + j*(-95) --222 + j*(240) -168 + j*(390) -433 + j*(71) -298 + j*(-221) -113 + j*(-276) --38 + j*(-285) --211 + j*(-148) --129 + j*(102) -140 + j*(42) -71 + j*(-243) --246 + j*(-169) --197 + j*(172) -141 + j*(163) -176 + j*(-131) --39 + j*(-188) --71 + j*(-68) --6 + j*(-113) --122 + j*(-194) --250 + j*(-72) --182 + j*(49) --130 + j*(2) --233 + j*(1) --279 + j*(167) --152 + j*(306) -4 + j*(311) -115 + j*(258) -196 + j*(161) -183 + j*(35) -96 + j*(2) -91 + j*(52) -163 + j*(17) -135 + j*(-98) -13 + j*(-98) -6 + j*(10) -126 + j*(-1) -124 + j*(-168) --72 + j*(-218) --180 + j*(-43) --50 + j*(76) -38 + j*(-34) --102 + j*(-103) --193 + j*(77) --8 + j*(222) -180 + j*(76) -91 + j*(-114) --70 + j*(-62) --25 + j*(64) -83 + j*(8) -17 + j*(-104) --108 + j*(-43) --68 + j*(95) -66 + j*(85) -87 + j*(-28) -7 + j*(-65) --32 + j*(-13) -8 + j*(21) -50 + j*(-14) -21 + j*(-77) --58 + j*(-66) --64 + j*(24) -18 + j*(32) -10 + j*(-45) --84 + j*(0) --7 + j*(138) -182 + j*(66) -154 + j*(-149) --35 + j*(-161) --43 + j*(-35) -47 + j*(-86) --53 + j*(-212) --228 + j*(-121) --199 + j*(75) --38 + j*(105) --4 + j*(0) --91 + j*(-20) --118 + j*(69) --45 + j*(129) -31 + j*(110) -70 + j*(59) -72 + j*(-11) -1 + j*(-50) --55 + j*(21) -40 + j*(91) -129 + j*(-38) --18 + j*(-161) --184 + j*(-22) --86 + j*(154) -49 + j*(109) -23 + j*(70) -81 + j*(145) -249 + j*(54) -211 + j*(-182) --6 + j*(-238) --119 + j*(-112) --94 + j*(-16) --45 + j*(4) --40 + j*(-24) --111 + j*(-7) --115 + j*(140) -83 + j*(215) -242 + j*(36) -144 + j*(-174) --55 + j*(-186) --177 + j*(-56) --151 + j*(151) -97 + j*(248) -300 + j*(8) -105 + j*(-250) --141 + j*(-107) --28 + j*(91) -112 + j*(-6) -44 + j*(-77) -77 + j*(-43) -118 + j*(-206) --136 + j*(-317) --323 + j*(-78) --179 + j*(105) --104 + j*(43) --173 + j*(98) --71 + j*(229) -88 + j*(177) -116 + j*(83) -140 + j*(18) -84 + j*(-103) --86 + j*(-54) --16 + j*(139) -209 + j*(42) -120 + j*(-204) --91 + j*(-161) --88 + j*(-69) --161 + j*(-97) --286 + j*(111) --36 + j*(347) -242 + j*(135) -69 + j*(-81) --37 + j*(124) -262 + j*(174) -354 + j*(-204) -2 + j*(-390) --237 + j*(-170) --171 + j*(34) --58 + j*(66) --5 + j*(24) --40 + j*(-21) --98 + j*(57) -17 + j*(168) -192 + j*(62) -145 + j*(-131) -6 + j*(-157) --46 + j*(-134) --132 + j*(-122) --197 + j*(14) --73 + j*(123) -19 + j*(25) --85 + j*(-29) --125 + j*(93) --18 + j*(140) -16 + j*(88) -4 + j*(108) -71 + j*(125) -114 + j*(65) -103 + j*(39) -145 + j*(17) -142 + j*(-93) -8 + j*(-139) --78 + j*(-27) --11 + j*(73) -76 + j*(73) -147 + j*(40) -218 + j*(-68) -157 + j*(-252) --81 + j*(-305) --247 + j*(-103) --129 + j*(117) -89 + j*(69) -76 + j*(-133) --103 + j*(-138) --116 + j*(15) --3 + j*(2) --71 + j*(-87) --168 + j*(54) -42 + j*(187) -231 + j*(-71) --33 + j*(-334) --361 + j*(-124) --255 + j*(204) --13 + j*(185) --21 + j*(64) --66 + j*(123) -37 + j*(165) -95 + j*(77) -58 + j*(33) -67 + j*(37) -74 + j*(-26) --30 + j*(-59) --108 + j*(63) -1 + j*(209) -211 + j*(170) -277 + j*(-49) -127 + j*(-202) --37 + j*(-149) --49 + j*(-40) --4 + j*(-18) -2 + j*(-22) -18 + j*(-16) -25 + j*(-37) -17 + j*(-31) -79 + j*(-47) -69 + j*(-206) --183 + j*(-267) --346 + j*(2) --140 + j*(216) -21 + j*(79) --124 + j*(21) --123 + j*(237) -144 + j*(259) -203 + j*(23) -47 + j*(-21) -65 + j*(90) -180 + j*(37) -152 + j*(-79) -76 + j*(-94) -55 + j*(-66) -95 + j*(-49) -170 + j*(-146) -53 + j*(-356) --285 + j*(-315) --371 + j*(47) --97 + j*(212) -49 + j*(59) --17 + j*(-6) --7 + j*(9) --35 + j*(-49) --129 + j*(38) -21 + j*(176) -208 + j*(-23) -5 + j*(-260) --254 + j*(-107) --191 + j*(100) --117 + j*(107) --118 + j*(190) -64 + j*(272) -217 + j*(83) -73 + j*(-70) --32 + j*(52) -101 + j*(117) -176 + j*(-16) -87 + j*(-118) --18 + j*(-108) --82 + j*(-35) --58 + j*(65) -35 + j*(84) -73 + j*(41) -102 + j*(31) -163 + j*(-49) -85 + j*(-190) --89 + j*(-156) --95 + j*(-13) --11 + j*(-6) --22 + j*(-48) --49 + j*(-43) --93 + j*(-39) --145 + j*(78) -29 + j*(209) -235 + j*(17) -60 + j*(-231) --168 + j*(-93) --69 + j*(47) --81 + j*(-54) --246 + j*(132) -73 + j*(419) -487 + j*(60) -174 + j*(-421) --269 + j*(-190) --85 + j*(129) -81 + j*(-65) --154 + j*(-115) --136 + j*(141) -96 + j*(64) --59 + j*(-118) --215 + j*(124) -84 + j*(286) -255 + j*(-15) --16 + j*(-170) --146 + j*(68) -57 + j*(194) -195 + j*(58) -163 + j*(-68) -100 + j*(-120) -36 + j*(-140) --8 + j*(-136) --66 + j*(-155) --198 + j*(-103) --226 + j*(107) --17 + j*(230) -150 + j*(91) -87 + j*(-49) -8 + j*(-22) -44 + j*(16) -93 + j*(-31) -83 + j*(-126) --42 + j*(-206) --228 + j*(-101) --180 + j*(163) -112 + j*(176) -170 + j*(-102) --66 + j*(-179) --119 + j*(-8) -2 + j*(-32) --122 + j*(-159) --315 + j*(13) --185 + j*(263) -39 + j*(226) -61 + j*(107) -42 + j*(103) -80 + j*(82) -66 + j*(42) -73 + j*(47) -92 + j*(-11) --8 + j*(-42) --36 + j*(92) -136 + j*(116) -161 + j*(-85) --52 + j*(-107) --78 + j*(107) -115 + j*(158) -198 + j*(37) -206 + j*(-30) -233 + j*(-147) -105 + j*(-296) --91 + j*(-243) --107 + j*(-116) --93 + j*(-111) --156 + j*(-58) --100 + j*(51) --8 + j*(5) --76 + j*(-36) --76 + j*(80) -89 + j*(67) -88 + j*(-130) --109 + j*(-154) --163 + j*(4) --71 + j*(72) --11 + j*(50) -28 + j*(6) -4 + j*(-98) --163 + j*(-115) --266 + j*(84) --107 + j*(284) -148 + j*(235) -229 + j*(-1) -65 + j*(-182) --173 + j*(-113) --206 + j*(139) -15 + j*(269) -215 + j*(127) -177 + j*(-83) -16 + j*(-129) --66 + j*(-47) --53 + j*(12) --54 + j*(39) --33 + j*(121) -116 + j*(142) -199 + j*(-38) -25 + j*(-173) --127 + j*(-29) --23 + j*(112) -71 + j*(55) -71 + j*(41) -174 + j*(1) -127 + j*(-229) --209 + j*(-211) --235 + j*(178) -154 + j*(242) -226 + j*(-96) --25 + j*(-138) --1 + j*(19) -86 + j*(-87) --87 + j*(-129) --107 + j*(76) -92 + j*(91) -117 + j*(-59) -75 + j*(-100) -46 + j*(-206) --205 + j*(-226) --292 + j*(119) -88 + j*(243) -202 + j*(-139) --165 + j*(-208) --170 + j*(136) -146 + j*(70) -25 + j*(-223) --239 + j*(-89) --125 + j*(107) --38 + j*(11) --151 + j*(28) --81 + j*(168) -54 + j*(91) --25 + j*(-14) --119 + j*(71) --67 + j*(187) -62 + j*(231) -211 + j*(141) -182 + j*(-53) -4 + j*(-33) -92 + j*(132) -301 + j*(-38) -110 + j*(-316) --187 + j*(-183) --132 + j*(46) --33 + j*(34) --54 + j*(67) -66 + j*(127) -159 + j*(-26) -22 + j*(-117) --34 + j*(-18) -18 + j*(-16) --23 + j*(-11) -64 + j*(69) -196 + j*(-114) --57 + j*(-320) --330 + j*(-72) --152 + j*(192) --2 + j*(98) --83 + j*(132) -121 + j*(293) -404 + j*(18) -167 + j*(-352) --204 + j*(-215) --169 + j*(91) -43 + j*(148) -187 + j*(39) -197 + j*(-179) --52 + j*(-305) --244 + j*(-71) --23 + j*(115) -124 + j*(-132) --166 + j*(-276) --333 + j*(7) --122 + j*(169) --35 + j*(35) --150 + j*(45) --89 + j*(186) -71 + j*(132) -36 + j*(-23) --124 + j*(-6) --153 + j*(177) -23 + j*(295) -215 + j*(187) -194 + j*(6) -92 + j*(1) -140 + j*(35) -164 + j*(-89) -0 + j*(-136) --56 + j*(47) -154 + j*(107) -251 + j*(-138) -10 + j*(-301) --205 + j*(-109) --66 + j*(111) -130 + j*(-16) --21 + j*(-204) --230 + j*(-14) --6 + j*(218) -248 + j*(-33) --30 + j*(-313) --336 + j*(-28) --74 + j*(287) -214 + j*(66) -23 + j*(-171) --169 + j*(6) --18 + j*(186) -165 + j*(110) -215 + j*(-51) -141 + j*(-221) --84 + j*(-267) --209 + j*(-71) --64 + j*(42) --12 + j*(-101) --207 + j*(-122) --271 + j*(94) --121 + j*(217) --10 + j*(194) -59 + j*(175) -134 + j*(99) -99 + j*(0) -27 + j*(18) -67 + j*(83) -180 + j*(54) -252 + j*(-110) -118 + j*(-344) --245 + j*(-345) --413 + j*(30) --139 + j*(291) -91 + j*(139) --4 + j*(32) -15 + j*(153) -206 + j*(59) -92 + j*(-194) --200 + j*(-92) --145 + j*(218) -156 + j*(247) -284 + j*(16) -176 + j*(-186) --37 + j*(-201) --136 + j*(-23) -21 + j*(102) -150 + j*(-71) --67 + j*(-228) --292 + j*(19) --73 + j*(336) -310 + j*(216) -332 + j*(-157) -56 + j*(-287) --94 + j*(-136) --10 + j*(-37) -43 + j*(-132) --78 + j*(-206) --198 + j*(-115) --190 + j*(-6) --173 + j*(41) --153 + j*(139) -8 + j*(206) -163 + j*(44) -36 + j*(-164) --196 + j*(-98) --203 + j*(114) --78 + j*(181) --26 + j*(182) -62 + j*(232) -237 + j*(156) -251 + j*(-74) -62 + j*(-168) --41 + j*(-62) -3 + j*(-13) --21 + j*(-46) --76 + j*(36) -42 + j*(139) -205 + j*(18) -135 + j*(-199) --91 + j*(-214) --186 + j*(-43) --100 + j*(76) --15 + j*(37) --72 + j*(-13) --146 + j*(102) --11 + j*(252) -202 + j*(170) -194 + j*(-18) -103 + j*(-23) -181 + j*(-23) -166 + j*(-228) --115 + j*(-272) --225 + j*(10) -1 + j*(140) -100 + j*(-16) --1 + j*(-50) -47 + j*(25) -138 + j*(-90) -16 + j*(-223) --127 + j*(-161) --138 + j*(-84) --164 + j*(-64) --204 + j*(10) --188 + j*(89) --175 + j*(176) --53 + j*(317) -230 + j*(272) -305 + j*(-43) -55 + j*(-187) --64 + j*(-13) -90 + j*(30) -88 + j*(-156) --129 + j*(-174) --196 + j*(16) --98 + j*(94) --83 + j*(88) --60 + j*(185) -122 + j*(215) -223 + j*(18) -56 + j*(-102) --25 + j*(59) -197 + j*(101) -256 + j*(-204) --93 + j*(-337) --296 + j*(-22) --63 + j*(194) -100 + j*(45) --1 + j*(-23) -26 + j*(77) -159 + j*(-20) -41 + j*(-190) --141 + j*(-94) --85 + j*(64) -17 + j*(31) --13 + j*(-13) --18 + j*(30) -35 + j*(13) -6 + j*(-37) --47 + j*(8) -11 + j*(77) -110 + j*(32) -112 + j*(-88) -20 + j*(-143) --46 + j*(-119) --78 + j*(-110) --158 + j*(-88) --196 + j*(45) --78 + j*(132) -3 + j*(45) --91 + j*(6) --100 + j*(129) -20 + j*(136) --5 + j*(57) --52 + j*(176) -173 + j*(255) -332 + j*(-16) -96 + j*(-234) --121 + j*(-66) --5 + j*(100) -100 + j*(18) -38 + j*(-21) -70 + j*(42) -169 + j*(-37) -86 + j*(-180) --71 + j*(-134) --54 + j*(-3) -48 + j*(-19) -24 + j*(-111) --67 + j*(-94) --61 + j*(-22) --18 + j*(-33) --43 + j*(-50) --28 + j*(-21) -10 + j*(-98) --150 + j*(-191) --346 + j*(9) --187 + j*(305) -134 + j*(229) -122 + j*(-38) --75 + j*(-45) --81 + j*(108) -35 + j*(128) -87 + j*(60) -73 + j*(-12) --1 + j*(-37) --43 + j*(38) -37 + j*(85) -69 + j*(6) --5 + j*(9) -47 + j*(98) -168 + j*(11) -84 + j*(-131) --36 + j*(-69) -14 + j*(-11) -0 + j*(-80) --106 + j*(-10) --7 + j*(136) -168 + j*(38) -94 + j*(-140) --55 + j*(-88) -1 + j*(16) -88 + j*(-73) --23 + j*(-194) --198 + j*(-105) --177 + j*(92) --8 + j*(129) -30 + j*(16) --53 + j*(25) -8 + j*(119) -132 + j*(45) -78 + j*(-69) -28 + j*(-37) -82 + j*(-84) --40 + j*(-209) --239 + j*(-71) --139 + j*(154) -50 + j*(103) -24 + j*(-12) --9 + j*(5) --3 + j*(-36) --116 + j*(-28) --100 + j*(141) -89 + j*(119) -43 + j*(-52) --103 + j*(43) -37 + j*(163) -112 + j*(13) --36 + j*(25) -91 + j*(203) -330 + j*(-5) -105 + j*(-291) --171 + j*(-92) -3 + j*(132) -169 + j*(-21) -66 + j*(-124) -59 + j*(-92) -61 + j*(-216) --166 + j*(-260) --288 + j*(-28) --144 + j*(124) --42 + j*(82) --34 + j*(65) -1 + j*(53) --16 + j*(18) --38 + j*(60) -28 + j*(83) -56 + j*(20) -27 + j*(11) -66 + j*(15) -75 + j*(-78) --39 + j*(-118) --107 + j*(-30) --64 + j*(39) --19 + j*(25) --37 + j*(-17) --118 + j*(4) --134 + j*(147) -31 + j*(228) -143 + j*(97) -49 + j*(32) -76 + j*(151) -277 + j*(72) -225 + j*(-197) --33 + j*(-203) --60 + j*(-19) -44 + j*(-20) --1 + j*(-74) --28 + j*(-5) -49 + j*(11) -67 + j*(-62) -25 + j*(-95) --18 + j*(-107) --86 + j*(-66) --52 + j*(37) -77 + j*(2) -51 + j*(-151) --102 + j*(-160) --155 + j*(-52) --123 + j*(10) --77 + j*(35) --37 + j*(-19) --151 + j*(-78) --279 + j*(107) --80 + j*(320) -166 + j*(162) -40 + j*(-37) --87 + j*(115) -116 + j*(214) -234 + j*(-7) -59 + j*(-147) --79 + j*(-52) --74 + j*(62) -0 + j*(154) -177 + j*(139) -238 + j*(-76) -45 + j*(-194) --65 + j*(-65) -10 + j*(-18) --23 + j*(-69) --79 + j*(30) -66 + j*(104) -166 + j*(-57) -38 + j*(-192) --109 + j*(-149) --170 + j*(-40) --140 + j*(96) -20 + j*(132) -81 + j*(-31) --105 + j*(-83) --165 + j*(148) -92 + j*(245) -236 + j*(13) -61 + j*(-146) --80 + j*(-19) -27 + j*(107) -159 + j*(11) -81 + j*(-136) --73 + j*(-70) -13 + j*(98) -228 + j*(-10) -141 + j*(-288) --147 + j*(-269) --175 + j*(-65) --96 + j*(-78) --225 + j*(-78) --224 + j*(160) -59 + j*(181) -83 + j*(-113) --226 + j*(-141) --305 + j*(163) --93 + j*(317) -67 + j*(287) -216 + j*(245) -365 + j*(32) -216 + j*(-264) --116 + j*(-228) --151 + j*(48) -54 + j*(88) -63 + j*(-82) --107 + j*(-66) --95 + j*(116) -88 + j*(127) -116 + j*(-40) --36 + j*(-79) --89 + j*(66) -40 + j*(155) -170 + j*(84) -196 + j*(-43) -141 + j*(-147) -37 + j*(-197) --66 + j*(-172) --134 + j*(-96) --136 + j*(9) --40 + j*(70) -35 + j*(-16) --76 + j*(-89) --170 + j*(64) -11 + j*(190) -152 + j*(13) --12 + j*(-109) --90 + j*(52) -77 + j*(80) -54 + j*(-91) --123 + j*(-16) --5 + j*(180) -223 + j*(46) -123 + j*(-204) --119 + j*(-177) --174 + j*(16) --52 + j*(139) -118 + j*(87) -125 + j*(-110) --74 + j*(-159) --132 + j*(8) --10 + j*(21) --101 + j*(-79) --238 + j*(122) -15 + j*(330) -260 + j*(115) -121 + j*(-69) -85 + j*(38) -250 + j*(-74) -77 + j*(-341) --238 + j*(-199) --146 + j*(61) -8 + j*(-41) --161 + j*(-130) --271 + j*(75) --132 + j*(226) --8 + j*(225) -101 + j*(228) -247 + j*(119) -230 + j*(-91) -74 + j*(-165) --19 + j*(-128) --75 + j*(-95) --127 + j*(-25) --117 + j*(65) --79 + j*(142) -49 + j*(235) -298 + j*(139) -308 + j*(-222) --73 + j*(-368) --323 + j*(-56) --135 + j*(231) -115 + j*(166) -129 + j*(3) -47 + j*(-31) -39 + j*(25) -129 + j*(23) -165 + j*(-124) -3 + j*(-222) --131 + j*(-92) --35 + j*(14) -15 + j*(-88) --119 + j*(-105) --146 + j*(41) --48 + j*(86) --21 + j*(86) -78 + j*(122) -211 + j*(-35) -49 + j*(-244) --173 + j*(-111) --52 + j*(62) -48 + j*(-91) --158 + j*(-151) --210 + j*(82) -1 + j*(119) --11 + j*(-60) --188 + j*(6) --103 + j*(201) -93 + j*(146) -90 + j*(-23) --31 + j*(-64) --115 + j*(-6) --129 + j*(91) --73 + j*(156) --34 + j*(175) -8 + j*(250) -199 + j*(287) -373 + j*(81) -259 + j*(-160) -71 + j*(-150) -55 + j*(-83) -28 + j*(-115) --59 + j*(-50) -13 + j*(64) -136 + j*(-8) -74 + j*(-134) --45 + j*(-95) --34 + j*(8) -62 + j*(33) -138 + j*(-57) -73 + j*(-204) --126 + j*(-192) --165 + j*(19) -34 + j*(80) -88 + j*(-112) --105 + j*(-161) --154 + j*(27) -13 + j*(75) -53 + j*(-72) --76 + j*(-108) --110 + j*(0) --18 + j*(25) -4 + j*(-70) --103 + j*(-115) --195 + j*(-31) --182 + j*(82) --122 + j*(148) --19 + j*(197) -145 + j*(121) -130 + j*(-141) --204 + j*(-209) --380 + j*(159) --49 + j*(431) -254 + j*(199) -109 + j*(-46) --40 + j*(69) -76 + j*(146) -103 + j*(42) -23 + j*(88) -150 + j*(185) -306 + j*(30) -202 + j*(-156) -64 + j*(-117) -97 + j*(-59) -127 + j*(-127) -59 + j*(-185) --7 + j*(-177) --52 + j*(-165) --100 + j*(-148) --152 + j*(-111) --204 + j*(-42) --206 + j*(82) --100 + j*(183) -35 + j*(167) -95 + j*(85) -105 + j*(21) -103 + j*(-40) -58 + j*(-119) --71 + j*(-144) --182 + j*(-22) --114 + j*(151) -64 + j*(158) -118 + j*(35) -75 + j*(-1) -117 + j*(-11) -117 + j*(-136) --44 + j*(-187) --122 + j*(-53) --40 + j*(-3) --56 + j*(-62) --124 + j*(5) --46 + j*(85) -11 + j*(18) --49 + j*(7) --18 + j*(71) -37 + j*(21) --21 + j*(4) -23 + j*(83) -139 + j*(-21) -6 + j*(-177) --162 + j*(-49) --58 + j*(91) -13 + j*(4) --66 + j*(15) -26 + j*(85) -84 + j*(-81) --144 + j*(-136) --197 + j*(111) -9 + j*(126) --88 + j*(-19) --234 + j*(235) -132 + j*(465) -454 + j*(116) -223 + j*(-209) -18 + j*(-98) -71 + j*(-66) --54 + j*(-120) --129 + j*(120) -187 + j*(238) -367 + j*(-93) -122 + j*(-313) --61 + j*(-222) --101 + j*(-175) --223 + j*(-97) --185 + j*(135) -59 + j*(154) -94 + j*(-38) --36 + j*(-45) --3 + j*(41) -57 + j*(-8) -19 + j*(-36) -42 + j*(-23) -47 + j*(-97) --47 + j*(-107) --39 + j*(-42) --11 + j*(-113) --172 + j*(-134) --220 + j*(83) -5 + j*(147) -57 + j*(-65) --144 + j*(-103) --192 + j*(58) --134 + j*(111) --146 + j*(188) -15 + j*(324) -254 + j*(173) -148 + j*(-80) --52 + j*(23) -94 + j*(183) -257 + j*(17) -134 + j*(-141) -34 + j*(-82) -66 + j*(-64) -51 + j*(-109) -25 + j*(-139) --74 + j*(-213) --311 + j*(-86) --231 + j*(309) -259 + j*(319) -364 + j*(-181) --62 + j*(-348) --226 + j*(-56) --77 + j*(29) --122 + j*(-21) --134 + j*(138) -69 + j*(139) -33 + j*(-44) --113 + j*(81) -110 + j*(214) -250 + j*(-69) --32 + j*(-199) --103 + j*(50) -117 + j*(23) --11 + j*(-203) --255 + j*(-18) --77 + j*(229) -121 + j*(95) -27 + j*(-4) -33 + j*(86) -142 + j*(11) -57 + j*(-103) --25 + j*(-51) --18 + j*(-39) --105 + j*(-1) --42 + j*(191) -243 + j*(138) -227 + j*(-188) --71 + j*(-205) --73 + j*(17) -75 + j*(-42) --54 + j*(-156) --165 + j*(5) --11 + j*(103) -47 + j*(-25) --75 + j*(-35) --68 + j*(111) -99 + j*(136) -199 + j*(-17) -103 + j*(-174) --64 + j*(-142) --41 + j*(-4) -87 + j*(-76) --41 + j*(-238) --248 + j*(-98) --129 + j*(101) -1 + j*(-13) --146 + j*(-62) --127 + j*(126) -78 + j*(33) --100 + j*(-194) --372 + j*(47) --139 + j*(343) -95 + j*(155) --95 + j*(54) --81 + j*(323) -264 + j*(278) -234 + j*(-66) --50 + j*(-19) -48 + j*(223) -284 + j*(112) -224 + j*(-91) -134 + j*(-91) -138 + j*(-142) --8 + j*(-211) --136 + j*(-45) -19 + j*(98) -153 + j*(-49) -11 + j*(-176) --105 + j*(-61) --22 + j*(21) -2 + j*(-51) --99 + j*(-24) --56 + j*(127) -128 + j*(113) -160 + j*(-46) -81 + j*(-84) -115 + j*(-97) -65 + j*(-268) --238 + j*(-262) --328 + j*(115) -54 + j*(303) -318 + j*(-23) -104 + j*(-321) --145 + j*(-260) --211 + j*(-163) --313 + j*(-78) --312 + j*(160) --65 + j*(249) -25 + j*(66) --114 + j*(55) --45 + j*(205) -119 + j*(95) --11 + j*(-44) --98 + j*(122) -107 + j*(158) -88 + j*(-76) --170 + j*(13) --18 + j*(310) -313 + j*(129) -136 + j*(-189) --126 + j*(-7) -83 + j*(190) -230 + j*(-31) -31 + j*(-122) -38 + j*(31) -165 + j*(-95) --62 + j*(-211) --161 + j*(81) -185 + j*(142) -208 + j*(-250) --206 + j*(-253) --192 + j*(141) -153 + j*(92) -63 + j*(-202) --186 + j*(-95) --95 + j*(91) -0 + j*(26) --43 + j*(40) -65 + j*(83) -115 + j*(-91) --76 + j*(-152) --131 + j*(6) --35 + j*(12) --111 + j*(-40) --175 + j*(98) --62 + j*(197) -20 + j*(194) -148 + j*(226) -348 + j*(36) -168 + j*(-298) --222 + j*(-152) --85 + j*(243) -297 + j*(108) -188 + j*(-240) --70 + j*(-167) -7 + j*(-41) -28 + j*(-183) --185 + j*(-180) --223 + j*(41) --71 + j*(119) -10 + j*(57) -11 + j*(-16) --75 + j*(-59) --168 + j*(67) --23 + j*(224) -180 + j*(88) -67 + j*(-110) --99 + j*(-6) -11 + j*(132) -138 + j*(37) -91 + j*(-74) -19 + j*(-91) --42 + j*(-75) --66 + j*(5) -25 + j*(30) -19 + j*(-80) --114 + j*(-31) --13 + j*(120) -162 + j*(-45) --66 + j*(-266) --356 + j*(-14) --152 + j*(330) -183 + j*(220) -167 + j*(-35) -26 + j*(-68) --13 + j*(-28) --38 + j*(4) --9 + j*(59) -47 + j*(23) --9 + j*(-20) --32 + j*(76) -98 + j*(88) -107 + j*(-59) --37 + j*(-49) -12 + j*(94) -174 + j*(8) -88 + j*(-179) --100 + j*(-131) --91 + j*(10) --30 + j*(9) --70 + j*(28) --10 + j*(131) -158 + j*(77) -141 + j*(-124) --57 + j*(-151) --112 + j*(18) -19 + j*(88) -95 + j*(-1) -59 + j*(-68) -23 + j*(-81) --15 + j*(-88) --47 + j*(-52) --13 + j*(-25) -2 + j*(-80) --78 + j*(-100) --107 + j*(-23) --51 + j*(-14) --87 + j*(-75) --187 + j*(-18) --170 + j*(98) --112 + j*(129) --97 + j*(177) -15 + j*(250) -170 + j*(165) -148 + j*(12) -64 + j*(20) -124 + j*(47) -161 + j*(-74) -35 + j*(-153) --64 + j*(-81) --49 + j*(-13) --33 + j*(-3) --28 + j*(11) --21 + j*(12) --44 + j*(30) --15 + j*(107) -117 + j*(91) -134 + j*(-70) --36 + j*(-107) --75 + j*(66) -117 + j*(116) -204 + j*(-89) -24 + j*(-230) --148 + j*(-127) --139 + j*(30) --41 + j*(98) -69 + j*(69) -103 + j*(-61) --25 + j*(-137) --119 + j*(-23) --18 + j*(52) -8 + j*(-64) --153 + j*(-33) --83 + j*(189) -197 + j*(93) -86 + j*(-235) --293 + j*(-129) --226 + j*(281) -158 + j*(278) -195 + j*(-12) -13 + j*(-35) -42 + j*(86) -158 + j*(42) -163 + j*(-66) -129 + j*(-132) -66 + j*(-199) --32 + j*(-218) --116 + j*(-207) --245 + j*(-177) --373 + j*(11) --266 + j*(280) -18 + j*(331) -182 + j*(159) -158 + j*(-23) -15 + j*(-107) --128 + j*(-4) --47 + j*(170) -136 + j*(105) -69 + j*(-54) --55 + j*(49) -98 + j*(155) -208 + j*(-11) -83 + j*(-102) -73 + j*(-41) -92 + j*(-145) --116 + j*(-157) --128 + j*(124) -205 + j*(135) -236 + j*(-214) --62 + j*(-278) --117 + j*(-98) --63 + j*(-123) --197 + j*(-114) --185 + j*(81) --5 + j*(66) --50 + j*(-69) --143 + j*(8) --59 + j*(42) --122 + j*(-60) --296 + j*(93) --145 + j*(368) -175 + j*(320) -255 + j*(62) -122 + j*(-95) --64 + j*(-74) --113 + j*(142) -149 + j*(253) -330 + j*(-47) -31 + j*(-283) --222 + j*(-14) -6 + j*(216) -192 + j*(39) -72 + j*(-78) -43 + j*(-16) -64 + j*(-79) --71 + j*(-67) --28 + j*(125) -212 + j*(54) -131 + j*(-217) --133 + j*(-146) --68 + j*(70) -76 + j*(-16) --59 + j*(-91) --95 + j*(104) -144 + j*(139) -205 + j*(-93) -36 + j*(-150) -50 + j*(-59) -124 + j*(-183) --73 + j*(-305) --228 + j*(-122) --81 + j*(-23) --100 + j*(-214) --424 + j*(-128) --380 + j*(317) -73 + j*(366) -153 + j*(8) --98 + j*(-6) --1 + j*(191) -185 + j*(2) --50 + j*(-177) --202 + j*(67) -40 + j*(162) -50 + j*(-89) --235 + j*(-28) --160 + j*(301) -161 + j*(273) -180 + j*(40) -69 + j*(28) -107 + j*(59) -119 + j*(-6) -87 + j*(-18) -110 + j*(-49) -35 + j*(-127) --82 + j*(-34) -22 + j*(100) -173 + j*(-21) -50 + j*(-208) --171 + j*(-125) --165 + j*(105) -37 + j*(181) -170 + j*(35) -77 + j*(-113) --60 + j*(-45) -16 + j*(80) -151 + j*(-3) -94 + j*(-148) --14 + j*(-153) --68 + j*(-142) --179 + j*(-107) --211 + j*(71) --58 + j*(149) --26 + j*(57) --117 + j*(155) -84 + j*(344) -407 + j*(170) -378 + j*(-184) -158 + j*(-296) -35 + j*(-284) --87 + j*(-274) --168 + j*(-157) --114 + j*(-103) --168 + j*(-168) --328 + j*(-48) --250 + j*(185) --42 + j*(190) --8 + j*(85) --21 + j*(76) --8 + j*(45) --76 + j*(54) --27 + j*(190) -190 + j*(132) -170 + j*(-142) --105 + j*(-183) --204 + j*(33) --92 + j*(165) -28 + j*(173) -127 + j*(103) -102 + j*(-33) --23 + j*(-9) -51 + j*(109) -190 + j*(-38) --11 + j*(-218) --225 + j*(-1) --25 + j*(212) -148 + j*(43) --7 + j*(-45) -1 + j*(132) -233 + j*(62) -165 + j*(-228) --132 + j*(-211) --180 + j*(21) --56 + j*(96) --8 + j*(82) -44 + j*(94) -104 + j*(25) -35 + j*(-51) --43 + j*(27) -45 + j*(134) -209 + j*(76) -254 + j*(-117) -107 + j*(-292) --150 + j*(-268) --263 + j*(-11) --60 + j*(197) -191 + j*(55) -93 + j*(-218) --197 + j*(-148) --148 + j*(162) -184 + j*(128) -178 + j*(-226) --180 + j*(-267) --271 + j*(51) --34 + j*(158) -41 + j*(13) --38 + j*(0) -1 + j*(40) -6 + j*(-18) --59 + j*(40) -88 + j*(136) -261 + j*(-80) -59 + j*(-350) --248 + j*(-250) --266 + j*(-21) --182 + j*(36) --177 + j*(53) --161 + j*(85) --193 + j*(107) --207 + j*(268) -27 + j*(402) -247 + j*(209) -129 + j*(17) -56 + j*(136) -258 + j*(120) -229 + j*(-168) --78 + j*(-160) --64 + j*(113) -170 + j*(59) -77 + j*(-148) --108 + j*(-31) -15 + j*(130) -151 + j*(8) -51 + j*(-105) --40 + j*(-45) --42 + j*(8) --46 + j*(79) -69 + j*(174) -252 + j*(73) -219 + j*(-144) -48 + j*(-170) -27 + j*(-79) -76 + j*(-110) -14 + j*(-173) --57 + j*(-125) --37 + j*(-83) --28 + j*(-112) --76 + j*(-127) --127 + j*(-107) --182 + j*(-55) --190 + j*(67) --52 + j*(153) -88 + j*(37) --12 + j*(-134) --209 + j*(-48) --156 + j*(166) -36 + j*(158) -42 + j*(40) -16 + j*(83) -163 + j*(47) -121 + j*(-222) --246 + j*(-230) --334 + j*(179) -50 + j*(338) -243 + j*(25) -16 + j*(-159) --142 + j*(-8) --72 + j*(122) -25 + j*(144) -138 + j*(94) -143 + j*(-86) --79 + j*(-124) --121 + j*(132) -185 + j*(173) -239 + j*(-182) --132 + j*(-284) --294 + j*(43) --78 + j*(240) -91 + j*(185) -195 + j*(122) -308 + j*(-75) -124 + j*(-369) --279 + j*(-296) --353 + j*(95) --79 + j*(262) -76 + j*(132) -30 + j*(67) -55 + j*(129) -194 + j*(81) -192 + j*(-132) --52 + j*(-206) --191 + j*(40) -42 + j*(218) -232 + j*(6) -36 + j*(-152) --55 + j*(59) -214 + j*(88) -226 + j*(-250) --139 + j*(-286) --190 + j*(41) -70 + j*(71) -55 + j*(-124) --89 + j*(-54) -37 + j*(49) -132 + j*(-125) --43 + j*(-244) --177 + j*(-129) --149 + j*(-38) --137 + j*(-24) --142 + j*(4) --150 + j*(25) --171 + j*(105) --52 + j*(214) -131 + j*(100) -37 + j*(-120) --204 + j*(-43) --158 + j*(200) -51 + j*(194) -59 + j*(61) -1 + j*(87) -82 + j*(112) -108 + j*(1) --3 + j*(-28) --23 + j*(77) -76 + j*(83) -66 + j*(-2) --14 + j*(46) -72 + j*(158) -244 + j*(79) -236 + j*(-113) -114 + j*(-178) -60 + j*(-178) --21 + j*(-221) --165 + j*(-146) --140 + j*(19) --21 + j*(2) --102 + j*(-72) --185 + j*(98) -42 + j*(233) -225 + j*(3) -28 + j*(-192) --140 + j*(-33) --7 + j*(78) -38 + j*(-54) --113 + j*(-42) --71 + j*(146) -151 + j*(107) -143 + j*(-125) --66 + j*(-162) --119 + j*(-9) --29 + j*(5) --102 + j*(-79) --268 + j*(76) --108 + j*(378) -293 + j*(308) -334 + j*(-91) -11 + j*(-167) -0 + j*(102) -304 + j*(29) -221 + j*(-356) --197 + j*(-358) --294 + j*(-16) --108 + j*(108) --43 + j*(82) -37 + j*(127) -197 + j*(-4) -68 + j*(-255) --235 + j*(-165) --197 + j*(137) -63 + j*(132) -61 + j*(-66) --91 + j*(-42) --37 + j*(91) -100 + j*(26) -60 + j*(-134) --96 + j*(-156) --182 + j*(-64) --192 + j*(13) --215 + j*(84) --202 + j*(231) --19 + j*(366) -247 + j*(267) -278 + j*(-31) -21 + j*(-142) --112 + j*(76) -100 + j*(225) -283 + j*(19) -115 + j*(-186) --77 + j*(-58) -45 + j*(105) -199 + j*(-28) -84 + j*(-192) --70 + j*(-128) --62 + j*(-35) --59 + j*(-8) --18 + j*(86) -176 + j*(46) -160 + j*(-254) --221 + j*(-291) --323 + j*(122) -72 + j*(262) -206 + j*(-103) --147 + j*(-211) --238 + j*(141) -100 + j*(235) -200 + j*(-59) --37 + j*(-152) --114 + j*(34) -33 + j*(107) -126 + j*(5) -100 + j*(-115) --15 + j*(-191) --179 + j*(-140) --224 + j*(51) --86 + j*(173) -54 + j*(123) -80 + j*(24) -42 + j*(-43) --30 + j*(-70) --118 + j*(-21) --136 + j*(110) --18 + j*(228) -181 + j*(202) -283 + j*(4) -170 + j*(-181) -2 + j*(-163) --1 + j*(-71) -43 + j*(-122) --56 + j*(-192) --161 + j*(-115) --156 + j*(-45) --197 + j*(-29) --255 + j*(115) --100 + j*(283) -112 + j*(202) -103 + j*(40) -40 + j*(46) -104 + j*(28) -45 + j*(-110) --158 + j*(-43) --114 + j*(212) -162 + j*(218) -224 + j*(-30) -39 + j*(-115) --30 + j*(13) -65 + j*(57) -101 + j*(-19) -54 + j*(-53) -42 + j*(-27) -81 + j*(-44) -65 + j*(-117) --36 + j*(-137) --88 + j*(-47) --27 + j*(-2) --19 + j*(-59) --105 + j*(-21) --44 + j*(110) -124 + j*(50) -86 + j*(-128) --64 + j*(-110) --41 + j*(-31) --33 + j*(-107) --197 + j*(-87) --207 + j*(129) --13 + j*(190) -45 + j*(83) -28 + j*(101) -155 + j*(90) -182 + j*(-108) --11 + j*(-187) --96 + j*(-67) --54 + j*(-40) --118 + j*(-52) --151 + j*(76) --30 + j*(140) -28 + j*(68) --1 + j*(66) -59 + j*(91) -106 + j*(13) -63 + j*(-46) -30 + j*(-65) --52 + j*(-95) --160 + j*(30) --26 + j*(209) -195 + j*(98) -116 + j*(-109) --30 + j*(-35) -85 + j*(37) -122 + j*(-138) --80 + j*(-183) --139 + j*(-16) --52 + j*(21) --83 + j*(8) --54 + j*(124) -121 + j*(78) -69 + j*(-126) --141 + j*(-68) --84 + j*(131) -74 + j*(79) -15 + j*(-7) -12 + j*(95) -184 + j*(45) -122 + j*(-194) --146 + j*(-146) --102 + j*(121) -168 + j*(62) -98 + j*(-232) --227 + j*(-185) --233 + j*(142) -51 + j*(192) -104 + j*(-26) --62 + j*(-37) --11 + j*(115) -159 + j*(13) -35 + j*(-194) --204 + j*(-81) --124 + j*(170) -105 + j*(130) -91 + j*(-57) --46 + j*(-47) --34 + j*(46) -18 + j*(25) --19 + j*(13) --1 + j*(90) -125 + j*(73) -142 + j*(-82) --7 + j*(-134) --57 + j*(-12) -56 + j*(1) -25 + j*(-146) --174 + j*(-100) --139 + j*(134) -93 + j*(115) -64 + j*(-90) --108 + j*(-28) --1 + j*(120) -132 + j*(-34) --59 + j*(-165) --207 + j*(35) --47 + j*(202) -100 + j*(136) -141 + j*(77) -220 + j*(-18) -155 + j*(-210) --57 + j*(-214) --86 + j*(-76) --43 + j*(-117) --204 + j*(-126) --249 + j*(128) -28 + j*(229) -165 + j*(-16) --25 + j*(-170) --192 + j*(-66) --209 + j*(88) --129 + j*(233) -81 + j*(271) -209 + j*(80) -72 + j*(-46) -18 + j*(77) -187 + j*(63) -157 + j*(-168) --95 + j*(-155) --91 + j*(73) -98 + j*(53) -54 + j*(-110) --90 + j*(-47) --23 + j*(76) -80 + j*(1) -1 + j*(-93) --100 + j*(-33) --98 + j*(78) --21 + j*(166) -151 + j*(190) -321 + j*(1) -203 + j*(-288) --123 + j*(-281) --194 + j*(-1) -13 + j*(88) -78 + j*(-65) --23 + j*(-102) --22 + j*(-69) --57 + j*(-141) --228 + j*(-72) --181 + j*(177) -86 + j*(182) -119 + j*(-33) -4 + j*(-56) -50 + j*(-43) --4 + j*(-202) --270 + j*(-153) --286 + j*(146) --64 + j*(211) --37 + j*(127) --25 + j*(225) -196 + j*(214) -241 + j*(-38) -58 + j*(-103) -51 + j*(-18) -80 + j*(-117) --96 + j*(-141) --125 + j*(45) -23 + j*(34) --79 + j*(-83) --216 + j*(120) -38 + j*(322) -293 + j*(91) -132 + j*(-173) --103 + j*(-79) --69 + j*(127) -124 + j*(176) -286 + j*(19) -222 + j*(-245) --86 + j*(-308) --252 + j*(-31) --45 + j*(192) -200 + j*(66) -170 + j*(-175) --29 + j*(-252) --189 + j*(-151) --204 + j*(22) --84 + j*(115) -18 + j*(67) -18 + j*(1) --2 + j*(-13) --11 + j*(-31) --57 + j*(-40) --103 + j*(17) --69 + j*(106) -46 + j*(123) -122 + j*(16) -49 + j*(-89) --46 + j*(-57) --28 + j*(-10) --50 + j*(-45) --136 + j*(37) --18 + j*(188) -182 + j*(63) -70 + j*(-157) --140 + j*(-64) --78 + j*(111) -35 + j*(95) -66 + j*(81) -185 + j*(32) -162 + j*(-202) --117 + j*(-233) --161 + j*(8) -6 + j*(-26) --165 + j*(-170) --362 + j*(101) --98 + j*(355) -115 + j*(180) --6 + j*(114) -75 + j*(283) -329 + j*(164) -286 + j*(-95) -141 + j*(-126) -104 + j*(-136) --6 + j*(-132) -7 + j*(22) -205 + j*(-46) -93 + j*(-307) --196 + j*(-183) --59 + j*(74) -151 + j*(-113) --83 + j*(-315) --296 + j*(-106) --171 + j*(77) --71 + j*(35) --72 + j*(4) --87 + j*(-40) --209 + j*(-25) --231 + j*(175) --37 + j*(239) --9 + j*(131) --40 + j*(248) -265 + j*(286) -378 + j*(-141) --78 + j*(-327) --289 + j*(93) -57 + j*(281) -181 + j*(31) -14 + j*(23) -139 + j*(173) -344 + j*(-11) -225 + j*(-270) -10 + j*(-289) --103 + j*(-218) --167 + j*(-113) --125 + j*(-10) --69 + j*(-30) --124 + j*(-33) --103 + j*(62) -4 + j*(15) --92 + j*(-112) --288 + j*(6) --251 + j*(276) -4 + j*(411) -286 + j*(305) -386 + j*(-4) -161 + j*(-228) --64 + j*(-95) -54 + j*(63) -171 + j*(-109) --41 + j*(-246) --227 + j*(-56) --119 + j*(155) -76 + j*(156) -170 + j*(5) -58 + j*(-159) --158 + j*(-61) --49 + j*(208) -276 + j*(100) -196 + j*(-252) --112 + j*(-204) --63 + j*(-6) -14 + j*(-114) --177 + j*(-100) --102 + j*(158) -188 + j*(33) -34 + j*(-267) --239 + j*(-119) --108 + j*(65) --68 + j*(-85) --296 + j*(1) --157 + j*(327) -224 + j*(201) -135 + j*(-182) --231 + j*(-141) --275 + j*(192) --20 + j*(354) -240 + j*(245) -291 + j*(-37) -54 + j*(-195) --135 + j*(-11) -25 + j*(170) -205 + j*(23) -100 + j*(-162) --71 + j*(-133) --131 + j*(-20) --115 + j*(113) -40 + j*(216) -250 + j*(104) -235 + j*(-154) -15 + j*(-248) --147 + j*(-132) --148 + j*(35) --17 + j*(121) -110 + j*(30) -44 + j*(-112) --106 + j*(-56) --55 + j*(97) -101 + j*(49) -62 + j*(-112) --109 + j*(-88) --120 + j*(91) -51 + j*(150) -152 + j*(11) -57 + j*(-103) --35 + j*(-41) -23 + j*(16) -52 + j*(-61) --41 + j*(-70) --28 + j*(37) -96 + j*(8) -76 + j*(-127) --33 + j*(-134) --47 + j*(-99) --90 + j*(-128) --177 + j*(-52) --112 + j*(59) --25 + j*(-8) --124 + j*(-69) --187 + j*(62) --61 + j*(129) --21 + j*(21) --146 + j*(18) --155 + j*(183) -16 + j*(247) -124 + j*(129) -52 + j*(31) --17 + j*(124) -143 + j*(221) -337 + j*(25) -185 + j*(-251) --93 + j*(-180) --52 + j*(13) -37 + j*(-83) --168 + j*(-117) --214 + j*(187) -127 + j*(282) -261 + j*(-25) -44 + j*(-146) --10 + j*(-31) -24 + j*(-95) --183 + j*(-95) --222 + j*(240) -168 + j*(390) -433 + j*(71) -298 + j*(-221) -113 + j*(-276) --38 + j*(-285) --211 + j*(-148) --129 + j*(102) -140 + j*(42) -71 + j*(-243) --246 + j*(-169) --197 + j*(172) -141 + j*(163) -176 + j*(-131) --39 + j*(-188) --71 + j*(-68) --6 + j*(-113) --122 + j*(-194) --250 + j*(-72) --182 + j*(49) --130 + j*(2) --233 + j*(1) --279 + j*(167) --152 + j*(306) -4 + j*(311) -115 + j*(258) -196 + j*(161) -183 + j*(35) -96 + j*(2) -91 + j*(52) -163 + j*(17) -135 + j*(-98) -13 + j*(-98) -6 + j*(10) -126 + j*(-1) -124 + j*(-168) --72 + j*(-218) --180 + j*(-43) --50 + j*(76) -38 + j*(-34) --102 + j*(-103) --193 + j*(77) --8 + j*(222) -180 + j*(76) -91 + j*(-114) --70 + j*(-62) --25 + j*(64) -83 + j*(8) -17 + j*(-104) --108 + j*(-43) --68 + j*(95) -66 + j*(85) -87 + j*(-28) -7 + j*(-65) --32 + j*(-13) -8 + j*(21) -50 + j*(-14) -21 + j*(-77) --58 + j*(-66) --64 + j*(24) -18 + j*(32) -10 + j*(-45) --84 + j*(0) --7 + j*(138) -182 + j*(66) -154 + j*(-149) --35 + j*(-161) --43 + j*(-35) -289 + j*(-105) -48 + j*(-267) --117 + j*(-80) -29 + j*(9) -35 + j*(-146) --147 + j*(-115) --127 + j*(57) --21 + j*(53) --33 + j*(38) -35 + j*(74) -91 + j*(-54) --83 + j*(-115) --143 + j*(86) -59 + j*(139) -90 + j*(-30) --27 + j*(-8) -72 + j*(67) -134 + j*(-110) --86 + j*(-178) --147 + j*(43) -63 + j*(65) -36 + j*(-163) --241 + j*(-127) --261 + j*(175) --10 + j*(271) -105 + j*(127) -33 + j*(82) -76 + j*(185) -282 + j*(139) -342 + j*(-134) -117 + j*(-313) --91 + j*(-217) --93 + j*(-85) --62 + j*(-66) --66 + j*(-48) --45 + j*(-54) --103 + j*(-93) --198 + j*(10) --96 + j*(158) -62 + j*(83) --5 + j*(-36) --83 + j*(56) -40 + j*(118) -115 + j*(-21) --5 + j*(-117) --124 + j*(-46) --124 + j*(76) --24 + j*(152) -101 + j*(85) -59 + j*(-54) --82 + j*(-16) --40 + j*(128) -96 + j*(98) -89 + j*(8) -78 + j*(14) -117 + j*(-49) -11 + j*(-134) --95 + j*(-16) -24 + j*(91) -124 + j*(-26) -34 + j*(-121) --38 + j*(-86) --65 + j*(-70) --132 + j*(-6) --73 + j*(136) -105 + j*(129) -165 + j*(-20) -114 + j*(-127) -27 + j*(-206) --149 + j*(-214) --279 + j*(-35) --199 + j*(165) --30 + j*(222) -127 + j*(180) -237 + j*(3) -117 + j*(-216) --130 + j*(-172) --134 + j*(24) --23 + j*(24) --66 + j*(-16) --55 + j*(66) -30 + j*(5) --110 + j*(-68) --191 + j*(171) -123 + j*(295) -298 + j*(-30) -11 + j*(-223) --153 + j*(-2) -4 + j*(105) -43 + j*(1) --23 + j*(31) -62 + j*(81) -114 + j*(-18) -42 + j*(-70) -21 + j*(-55) --17 + j*(-88) --118 + j*(-25) --51 + j*(135) -152 + j*(98) -173 + j*(-116) --1 + j*(-206) --134 + j*(-121) --135 + j*(-4) --72 + j*(30) --74 + j*(0) --143 + j*(57) --77 + j*(211) -144 + j*(200) -202 + j*(-10) -59 + j*(-81) -58 + j*(10) -178 + j*(-93) -22 + j*(-322) --337 + j*(-206) --330 + j*(221) -78 + j*(327) -239 + j*(-14) --35 + j*(-155) --123 + j*(98) -151 + j*(136) -168 + j*(-165) --141 + j*(-185) --166 + j*(93) -47 + j*(113) -43 + j*(-6) -30 + j*(49) -165 + j*(-33) -17 + j*(-255) --269 + j*(-81) --86 + j*(231) -225 + j*(40) -30 + j*(-259) --252 + j*(-91) --139 + j*(146) -13 + j*(98) -14 + j*(58) -77 + j*(35) -42 + j*(-102) --147 + j*(-42) --55 + j*(191) -230 + j*(76) -115 + j*(-262) --256 + j*(-185) --249 + j*(168) -25 + j*(216) -93 + j*(48) -23 + j*(21) -58 + j*(40) -56 + j*(-28) --37 + j*(-1) -32 + j*(119) -198 + j*(11) -76 + j*(-219) --213 + j*(-105) --132 + j*(235) -230 + j*(217) -286 + j*(-113) -52 + j*(-210) --11 + j*(-78) -75 + j*(-99) --7 + j*(-212) --186 + j*(-150) --212 + j*(49) --55 + j*(184) -151 + j*(121) -186 + j*(-97) -4 + j*(-198) --103 + j*(-67) -1 + j*(5) -44 + j*(-101) --55 + j*(-142) --87 + j*(-94) --101 + j*(-129) --243 + j*(-112) --301 + j*(93) --132 + j*(234) -18 + j*(151) --12 + j*(62) --49 + j*(107) -35 + j*(147) -117 + j*(44) -16 + j*(-88) --175 + j*(0) --128 + j*(248) -146 + j*(272) -226 + j*(30) -36 + j*(-52) --14 + j*(125) -177 + j*(180) -288 + j*(15) -226 + j*(-129) -146 + j*(-189) -43 + j*(-238) --108 + j*(-192) --154 + j*(-26) --35 + j*(66) -40 + j*(-11) --47 + j*(-35) --35 + j*(124) -231 + j*(130) -330 + j*(-210) -6 + j*(-432) --267 + j*(-223) --188 + j*(-30) --155 + j*(-62) --239 + j*(41) --90 + j*(183) -37 + j*(34) --144 + j*(-7) --110 + j*(267) -263 + j*(215) -240 + j*(-197) --127 + j*(-203) --124 + j*(60) -16 + j*(-4) --152 + j*(-30) --110 + j*(262) -289 + j*(213) -280 + j*(-238) --146 + j*(-282) --222 + j*(64) -23 + j*(141) -82 + j*(-6) -25 + j*(-49) -6 + j*(-81) --108 + j*(-105) --194 + j*(47) --64 + j*(187) -83 + j*(114) -59 + j*(8) -0 + j*(14) --1 + j*(57) -37 + j*(90) -122 + j*(75) -168 + j*(-39) -73 + j*(-146) --55 + j*(-95) --36 + j*(14) -54 + j*(-6) -14 + j*(-96) --99 + j*(-51) --68 + j*(88) -85 + j*(91) -134 + j*(-51) -41 + j*(-154) --95 + j*(-151) --206 + j*(-25) --144 + j*(183) -107 + j*(202) -188 + j*(-37) --20 + j*(-119) --62 + j*(71) -147 + j*(68) -124 + j*(-173) --122 + j*(-161) --127 + j*(53) -21 + j*(59) -6 + j*(-20) --13 + j*(25) -59 + j*(1) -4 + j*(-86) --95 + j*(-6) -8 + j*(105) -144 + j*(-4) -68 + j*(-172) --110 + j*(-169) --196 + j*(-29) --133 + j*(106) --3 + j*(113) -34 + j*(15) --41 + j*(-21) --91 + j*(33) --90 + j*(110) --18 + j*(216) -197 + j*(218) -314 + j*(-42) -87 + j*(-242) --115 + j*(-71) -33 + j*(80) -140 + j*(-82) --29 + j*(-170) --99 + j*(-30) --1 + j*(-6) --40 + j*(-76) --98 + j*(8) -1 + j*(52) -15 + j*(-54) --93 + j*(-42) --65 + j*(50) --20 + j*(-1) --129 + j*(8) --103 + j*(194) -134 + j*(193) -154 + j*(-35) --39 + j*(-37) -11 + j*(146) -216 + j*(68) -156 + j*(-149) --17 + j*(-116) -37 + j*(-21) -90 + j*(-150) --112 + j*(-232) --263 + j*(-30) --138 + j*(153) -8 + j*(112) --6 + j*(47) --35 + j*(86) -14 + j*(156) -151 + j*(177) -316 + j*(31) -255 + j*(-251) --49 + j*(-311) --167 + j*(-69) -13 + j*(4) -6 + j*(-192) --267 + j*(-154) --273 + j*(182) -54 + j*(267) -185 + j*(0) --18 + j*(-135) --144 + j*(32) -2 + j*(172) -166 + j*(59) -109 + j*(-117) --37 + j*(-109) --45 + j*(-27) --28 + j*(-60) --139 + j*(-47) --143 + j*(141) -78 + j*(190) -168 + j*(-18) -1 + j*(-113) --71 + j*(6) -6 + j*(42) -5 + j*(3) --3 + j*(49) -91 + j*(45) -108 + j*(-82) --16 + j*(-148) --133 + j*(-73) --136 + j*(76) -23 + j*(173) -211 + j*(23) -102 + j*(-249) --216 + j*(-225) --303 + j*(62) --138 + j*(218) --2 + j*(214) -100 + j*(173) -144 + j*(47) -25 + j*(-8) -6 + j*(151) -246 + j*(177) -357 + j*(-109) -131 + j*(-318) --112 + j*(-233) --158 + j*(-30) --19 + j*(103) -180 + j*(0) -107 + j*(-271) --215 + j*(-262) --282 + j*(39) --81 + j*(137) --29 + j*(65) -1 + j*(115) -158 + j*(27) -47 + j*(-217) --241 + j*(-107) --150 + j*(170) -54 + j*(88) --59 + j*(-16) --83 + j*(154) -124 + j*(134) -70 + j*(-66) --105 + j*(45) -65 + j*(219) -265 + j*(42) -152 + j*(-168) --22 + j*(-149) --83 + j*(-40) --25 + j*(85) -170 + j*(56) -179 + j*(-217) --138 + j*(-293) --273 + j*(-1) --75 + j*(133) --13 + j*(32) --70 + j*(78) -46 + j*(151) -146 + j*(57) -153 + j*(-16) -195 + j*(-137) -28 + j*(-334) --276 + j*(-197) --188 + j*(105) -34 + j*(-1) --150 + j*(-147) --267 + j*(112) -5 + j*(197) -16 + j*(-44) --216 + j*(57) --28 + j*(312) -238 + j*(98) -31 + j*(-144) --156 + j*(45) --7 + j*(180) -56 + j*(98) -30 + j*(136) -173 + j*(168) -258 + j*(-6) -145 + j*(-132) -42 + j*(-111) -1 + j*(-65) -16 + j*(-4) -90 + j*(-25) -50 + j*(-115) --30 + j*(-59) -59 + j*(-30) -15 + j*(-192) --250 + j*(-86) --112 + j*(277) -327 + j*(137) -206 + j*(-332) --237 + j*(-243) --171 + j*(117) -79 + j*(52) --7 + j*(-91) --53 + j*(17) -75 + j*(-9) -6 + j*(-153) --129 + j*(-91) --99 + j*(-10) --106 + j*(-25) --136 + j*(52) --40 + j*(88) --48 + j*(1) --161 + j*(84) --45 + j*(264) -179 + j*(209) -245 + j*(39) -233 + j*(-105) -105 + j*(-275) --171 + j*(-233) --192 + j*(54) -74 + j*(65) -41 + j*(-211) --262 + j*(-182) --293 + j*(94) --141 + j*(161) --134 + j*(158) --73 + j*(276) -132 + j*(254) -175 + j*(54) -16 + j*(-18) --84 + j*(126) -39 + j*(310) -330 + j*(296) -501 + j*(-6) -334 + j*(-305) -71 + j*(-325) --45 + j*(-229) --115 + j*(-142) --98 + j*(11) -86 + j*(33) -119 + j*(-179) --106 + j*(-235) --180 + j*(-46) --73 + j*(-6) --128 + j*(-57) --189 + j*(103) -11 + j*(227) -194 + j*(70) -141 + j*(-124) --1 + j*(-195) --173 + j*(-159) --265 + j*(54) --91 + j*(255) -147 + j*(177) -175 + j*(-4) -122 + j*(-93) -39 + j*(-185) --155 + j*(-162) --191 + j*(64) -11 + j*(116) -21 + j*(-49) --126 + j*(13) --3 + j*(163) -136 + j*(6) --46 + j*(-89) --78 + j*(132) -209 + j*(125) -206 + j*(-209) --115 + j*(-246) --169 + j*(-5) --25 + j*(13) --78 + j*(-70) --147 + j*(35) --38 + j*(98) --1 + j*(-1) --103 + j*(-11) --120 + j*(90) --57 + j*(137) --13 + j*(147) -47 + j*(153) -107 + j*(101) -100 + j*(24) -37 + j*(-1) --18 + j*(52) -26 + j*(156) -185 + j*(162) -270 + j*(-8) -148 + j*(-137) -51 + j*(-60) -148 + j*(-20) -189 + j*(-180) -4 + j*(-284) --164 + j*(-153) --118 + j*(13) -3 + j*(23) -24 + j*(-56) --43 + j*(-78) --88 + j*(-6) --18 + j*(78) -110 + j*(32) -114 + j*(-117) --15 + j*(-175) --87 + j*(-96) --46 + j*(-64) --71 + j*(-127) --206 + j*(-91) --226 + j*(105) --23 + j*(203) -134 + j*(45) -30 + j*(-124) --115 + j*(-62) --65 + j*(28) --31 + j*(-54) --179 + j*(-63) --210 + j*(136) --16 + j*(198) -36 + j*(40) --106 + j*(38) --68 + j*(192) -78 + j*(156) -47 + j*(64) -39 + j*(136) -185 + j*(86) -110 + j*(-131) --153 + j*(-52) --91 + j*(232) -165 + j*(208) -156 + j*(53) -134 + j*(125) -352 + j*(78) -346 + j*(-262) --13 + j*(-349) --147 + j*(-60) -64 + j*(48) -127 + j*(-127) --36 + j*(-159) --47 + j*(2) -148 + j*(4) -195 + j*(-245) --71 + j*(-416) --358 + j*(-235) --324 + j*(68) --119 + j*(122) --91 + j*(37) --129 + j*(89) --40 + j*(146) -21 + j*(93) -28 + j*(99) -151 + j*(76) -176 + j*(-152) --89 + j*(-262) --268 + j*(-39) --136 + j*(136) --42 + j*(90) --69 + j*(110) -40 + j*(185) -185 + j*(63) -122 + j*(-134) --73 + j*(-173) --218 + j*(-44) --208 + j*(163) --20 + j*(275) -141 + j*(173) -112 + j*(64) -101 + j*(95) -206 + j*(52) -184 + j*(-124) --6 + j*(-166) --108 + j*(-8) --1 + j*(148) -205 + j*(106) -245 + j*(-127) -27 + j*(-231) --72 + j*(-45) -124 + j*(-6) -107 + j*(-274) --233 + j*(-255) --246 + j*(96) -51 + j*(117) -33 + j*(-96) --96 + j*(-16) -52 + j*(31) -20 + j*(-190) --269 + j*(-102) --158 + j*(219) -146 + j*(103) -16 + j*(-148) --162 + j*(-1) --6 + j*(86) --26 + j*(-93) --250 + j*(21) --105 + j*(300) -186 + j*(184) -116 + j*(-55) --38 + j*(-11) --4 + j*(71) -16 + j*(56) -22 + j*(95) -110 + j*(95) -133 + j*(8) -105 + j*(-18) -121 + j*(-63) -32 + j*(-133) --62 + j*(-13) -107 + j*(81) -227 + j*(-165) --63 + j*(-356) --326 + j*(-103) --173 + j*(166) -21 + j*(103) --13 + j*(16) --28 + j*(69) -35 + j*(64) -17 + j*(31) -24 + j*(100) -172 + j*(95) -235 + j*(-98) -76 + j*(-238) --76 + j*(-169) --74 + j*(-90) --94 + j*(-104) --181 + j*(-21) --91 + j*(144) -133 + j*(70) -83 + j*(-201) --218 + j*(-201) --285 + j*(86) --70 + j*(182) --14 + j*(47) --133 + j*(74) --64 + j*(236) -134 + j*(196) -145 + j*(21) -33 + j*(-3) -31 + j*(71) -93 + j*(63) -103 + j*(27) -136 + j*(8) -159 + j*(-101) -6 + j*(-204) --166 + j*(-51) --32 + j*(163) -197 + j*(45) -89 + j*(-181) --113 + j*(-66) -34 + j*(115) -224 + j*(-70) -40 + j*(-300) --203 + j*(-174) --153 + j*(20) --46 + j*(-1) --86 + j*(-54) --144 + j*(-4) --142 + j*(78) --77 + j*(152) -35 + j*(143) -64 + j*(58) -30 + j*(57) -103 + j*(73) -147 + j*(-69) --13 + j*(-156) --113 + j*(-19) --8 + j*(49) -1 + j*(-51) --122 + j*(-18) --88 + j*(131) -46 + j*(125) -52 + j*(45) -18 + j*(74) -99 + j*(122) -229 + j*(40) -226 + j*(-179) --26 + j*(-305) --270 + j*(-82) --103 + j*(228) -225 + j*(115) -159 + j*(-190) --81 + j*(-153) --35 + j*(-6) -34 + j*(-107) --125 + j*(-144) --168 + j*(22) --47 + j*(45) --95 + j*(-20) --159 + j*(114) -14 + j*(233) -197 + j*(102) -174 + j*(-106) --4 + j*(-222) --247 + j*(-124) --266 + j*(206) -88 + j*(342) -296 + j*(18) -17 + j*(-190) --146 + j*(75) -149 + j*(204) -288 + j*(-123) --25 + j*(-312) --264 + j*(-69) --137 + j*(181) -74 + j*(180) -169 + j*(55) -150 + j*(-76) -47 + j*(-137) --26 + j*(-86) -4 + j*(-62) --24 + j*(-129) --163 + j*(-97) --177 + j*(95) -24 + j*(166) -134 + j*(-13) --17 + j*(-141) --153 + j*(-25) --85 + j*(95) --29 + j*(76) --37 + j*(125) -110 + j*(194) -278 + j*(7) -135 + j*(-240) --113 + j*(-179) --115 + j*(-4) --42 + j*(2) --67 + j*(11) --9 + j*(69) -59 + j*(-32) --93 + j*(-112) --205 + j*(74) --33 + j*(229) -126 + j*(125) -100 + j*(23) -87 + j*(9) -70 + j*(-52) --30 + j*(-29) -18 + j*(99) -185 + j*(21) -101 + j*(-180) --99 + j*(-108) --31 + j*(54) -78 + j*(-33) --46 + j*(-89) --52 + j*(81) -185 + j*(49) -157 + j*(-255) --177 + j*(-282) --271 + j*(8) --87 + j*(125) --6 + j*(40) --25 + j*(14) --21 + j*(-10) --103 + j*(-24) --145 + j*(128) -56 + j*(224) -201 + j*(26) -47 + j*(-132) --82 + j*(-22) --1 + j*(52) -16 + j*(-13) --42 + j*(16) -16 + j*(66) -49 + j*(-5) --40 + j*(-9) --18 + j*(112) -144 + j*(107) -204 + j*(-70) -72 + j*(-212) --123 + j*(-176) --181 + j*(23) --6 + j*(134) -121 + j*(-31) --50 + j*(-162) --195 + j*(7) --65 + j*(153) -37 + j*(91) -40 + j*(92) -170 + j*(61) -163 + j*(-193) --170 + j*(-240) --288 + j*(107) --1 + j*(282) -185 + j*(114) -162 + j*(-13) -153 + j*(-107) --3 + j*(-224) --206 + j*(-63) --57 + j*(169) -165 + j*(22) -11 + j*(-170) --147 + j*(-13) -1 + j*(107) -85 + j*(-23) --13 + j*(-83) --57 + j*(-38) --77 + j*(-19) --95 + j*(47) --35 + j*(86) --41 + j*(71) --32 + j*(205) -263 + j*(254) -446 + j*(-144) -64 + j*(-469) --317 + j*(-196) --170 + j*(134) -43 + j*(57) --21 + j*(-52) --77 + j*(8) --59 + j*(57) --23 + j*(123) -140 + j*(134) -221 + j*(-90) --5 + j*(-235) --171 + j*(-45) --26 + j*(109) -98 + j*(6) -53 + j*(-85) -20 + j*(-107) --38 + j*(-162) --164 + j*(-141) --222 + j*(-29) --217 + j*(60) --197 + j*(170) --65 + j*(260) -76 + j*(199) -81 + j*(114) -95 + j*(112) -139 + j*(42) -67 + j*(-21) -35 + j*(58) -151 + j*(43) -117 + j*(-108) --39 + j*(-65) -33 + j*(71) -153 + j*(-46) -3 + j*(-164) --120 + j*(-2) -28 + j*(127) -170 + j*(25) -165 + j*(-112) -88 + j*(-227) --107 + j*(-260) --238 + j*(-64) --82 + j*(87) -16 + j*(-58) --175 + j*(-95) --187 + j*(146) -65 + j*(148) -33 + j*(-88) --204 + j*(-8) --112 + j*(245) -112 + j*(188) -80 + j*(72) -94 + j*(163) -308 + j*(91) -301 + j*(-218) -12 + j*(-330) --177 + j*(-164) --170 + j*(13) --62 + j*(122) -107 + j*(92) -132 + j*(-90) --40 + j*(-125) --41 + j*(42) -165 + j*(-6) -113 + j*(-285) --213 + j*(-308) --335 + j*(-26) --180 + j*(148) --30 + j*(113) -8 + j*(11) --77 + j*(-79) --247 + j*(-12) --247 + j*(233) --6 + j*(336) -141 + j*(191) -93 + j*(113) -146 + j*(161) -292 + j*(35) -192 + j*(-216) --88 + j*(-197) --121 + j*(41) -64 + j*(60) -31 + j*(-109) --173 + j*(-31) --81 + j*(224) -200 + j*(147) -132 + j*(-132) --136 + j*(-41) --18 + j*(240) -288 + j*(127) -226 + j*(-165) -8 + j*(-162) --4 + j*(-52) -6 + j*(-53) --10 + j*(20) -144 + j*(53) -215 + j*(-162) -6 + j*(-276) --84 + j*(-134) -16 + j*(-155) --129 + j*(-308) --391 + j*(-144) --329 + j*(155) --134 + j*(208) --63 + j*(195) -69 + j*(210) -174 + j*(31) --1 + j*(-110) --136 + j*(81) -98 + j*(218) -280 + j*(-43) -37 + j*(-285) --244 + j*(-103) --130 + j*(182) -132 + j*(116) -78 + j*(-113) --134 + j*(-38) --12 + j*(190) -277 + j*(32) -137 + j*(-336) --269 + j*(-279) --306 + j*(73) --84 + j*(141) --79 + j*(33) --160 + j*(114) --60 + j*(229) -64 + j*(197) -116 + j*(135) -141 + j*(62) -92 + j*(-4) -40 + j*(38) -105 + j*(69) -138 + j*(-11) -86 + j*(-39) -103 + j*(-30) -90 + j*(-114) --45 + j*(-99) --21 + j*(61) -155 + j*(28) -143 + j*(-152) -14 + j*(-182) --38 + j*(-177) --177 + j*(-168) --257 + j*(71) -22 + j*(226) -203 + j*(-59) --80 + j*(-229) --218 + j*(40) -30 + j*(115) -11 + j*(-123) --260 + j*(-18) --127 + j*(306) -204 + j*(222) -184 + j*(-29) -74 + j*(-21) -145 + j*(-28) -97 + j*(-173) --65 + j*(-141) --32 + j*(-24) -42 + j*(-103) --76 + j*(-190) --200 + j*(-114) --247 + j*(-19) --295 + j*(141) --132 + j*(388) -254 + j*(333) -330 + j*(-62) -25 + j*(-201) --71 + j*(1) -73 + j*(-6) --41 + j*(-155) --235 + j*(30) --35 + j*(269) -218 + j*(110) -127 + j*(-100) -16 + j*(-71) -24 + j*(-86) --116 + j*(-117) --199 + j*(104) -41 + j*(250) -223 + j*(57) -123 + j*(-101) -54 + j*(-88) -33 + j*(-143) --110 + j*(-144) --150 + j*(2) --69 + j*(37) --112 + j*(37) --70 + j*(188) -166 + j*(158) -164 + j*(-104) --70 + j*(-116) --74 + j*(55) -14 + j*(47) --10 + j*(61) -119 + j*(114) -215 + j*(-118) --82 + j*(-257) --247 + j*(54) -39 + j*(202) -122 + j*(-38) --81 + j*(-23) -25 + j*(167) -210 + j*(18) -73 + j*(-124) -33 + j*(-14) -141 + j*(-105) --53 + j*(-239) --199 + j*(8) -69 + j*(123) -135 + j*(-160) --154 + j*(-180) --127 + j*(86) -100 + j*(2) --37 + j*(-207) --245 + j*(-57) --139 + j*(126) --26 + j*(81) --37 + j*(59) -4 + j*(56) --21 + j*(-15) --119 + j*(55) --18 + j*(194) -148 + j*(102) -82 + j*(-47) --7 + j*(17) -97 + j*(55) -132 + j*(-103) --51 + j*(-179) --177 + j*(-28) --92 + j*(119) -30 + j*(105) -57 + j*(37) -43 + j*(4) -25 + j*(-22) --23 + j*(-17) --28 + j*(54) -62 + j*(68) -92 + j*(-38) --19 + j*(-83) --71 + j*(21) -14 + j*(81) -79 + j*(25) -70 + j*(-34) -31 + j*(-78) --53 + j*(-79) --98 + j*(21) --20 + j*(96) -56 + j*(66) -81 + j*(31) -117 + j*(-33) -43 + j*(-134) --94 + j*(-61) --4 + j*(74) -112 + j*(-68) --100 + j*(-173) --209 + j*(107) -116 + j*(230) -250 + j*(-109) --65 + j*(-243) --179 + j*(18) -12 + j*(88) -21 + j*(-33) --46 + j*(14) -36 + j*(38) -23 + j*(-49) --44 + j*(4) -50 + j*(33) -29 + j*(-98) --134 + j*(-14) -22 + j*(192) -293 + j*(-10) -109 + j*(-337) --204 + j*(-235) --176 + j*(-43) --158 + j*(-93) --324 + j*(-2) --251 + j*(276) -33 + j*(293) -100 + j*(108) -23 + j*(74) -47 + j*(98) -50 + j*(59) -31 + j*(103) -155 + j*(132) -241 + j*(-50) -63 + j*(-202) --117 + j*(-78) --51 + j*(88) -74 + j*(75) -110 + j*(15) -144 + j*(-58) -79 + j*(-200) --139 + j*(-191) --190 + j*(33) --8 + j*(96) -7 + j*(-53) --159 + j*(1) --78 + j*(213) -152 + j*(168) -161 + j*(-13) -86 + j*(-45) -86 + j*(-71) --5 + j*(-117) --72 + j*(0) -64 + j*(57) -101 + j*(-98) --54 + j*(-114) --33 + j*(19) -74 + j*(-61) --57 + j*(-158) --146 + j*(-16) --35 + j*(30) --71 + j*(-45) --130 + j*(91) -86 + j*(144) -123 + j*(-132) --199 + j*(-146) --197 + j*(214) -173 + j*(206) -166 + j*(-143) --147 + j*(-138) --156 + j*(122) -28 + j*(158) -74 + j*(79) -92 + j*(67) -139 + j*(16) -139 + j*(-55) -127 + j*(-139) -9 + j*(-258) --230 + j*(-187) --246 + j*(93) --12 + j*(165) -50 + j*(8) --50 + j*(1) -4 + j*(67) -45 + j*(-31) --97 + j*(-49) --100 + j*(129) -100 + j*(128) -93 + j*(-74) --117 + j*(-50) --92 + j*(185) -175 + j*(204) -278 + j*(-47) -117 + j*(-231) --79 + j*(-203) --175 + j*(-86) --193 + j*(62) --84 + j*(206) -129 + j*(198) -231 + j*(-6) -102 + j*(-179) --88 + j*(-148) --156 + j*(2) --88 + j*(147) -98 + j*(192) -267 + j*(23) -168 + j*(-235) --110 + j*(-236) --180 + j*(1) --2 + j*(80) -46 + j*(-66) --109 + j*(-97) --160 + j*(77) -1 + j*(176) -139 + j*(74) -117 + j*(-64) -33 + j*(-117) --59 + j*(-117) --161 + j*(-37) --133 + j*(150) -104 + j*(219) -291 + j*(-16) -139 + j*(-310) --199 + j*(-314) --378 + j*(-46) --284 + j*(239) --25 + j*(341) -194 + j*(214) -214 + j*(10) -110 + j*(-87) -23 + j*(-93) --47 + j*(-53) --41 + j*(39) -58 + j*(28) -17 + j*(-89) --136 + j*(-11) --37 + j*(188) -182 + j*(91) -91 + j*(-105) --46 + j*(6) -108 + j*(94) -180 + j*(-86) -37 + j*(-130) -85 + j*(-60) -135 + j*(-260) --185 + j*(-387) --421 + j*(-73) --231 + j*(197) --42 + j*(148) --9 + j*(95) -47 + j*(28) --54 + j*(-99) --247 + j*(40) --104 + j*(290) -146 + j*(186) -71 + j*(12) -3 + j*(115) -165 + j*(115) -146 + j*(-84) --47 + j*(-49) -16 + j*(131) -212 + j*(54) -180 + j*(-160) --13 + j*(-214) --140 + j*(-92) --93 + j*(52) -25 + j*(36) --27 + j*(-58) --121 + j*(58) -49 + j*(178) -180 + j*(-21) --45 + j*(-127) --101 + j*(151) -255 + j*(185) -320 + j*(-228) --79 + j*(-355) --247 + j*(-40) --45 + j*(126) -95 + j*(31) -101 + j*(-80) -32 + j*(-185) --139 + j*(-178) --192 + j*(-7) --73 + j*(47) --81 + j*(-33) --180 + j*(51) --69 + j*(201) -110 + j*(124) -83 + j*(-42) --50 + j*(-42) --71 + j*(80) -69 + j*(144) -213 + j*(-8) -88 + j*(-250) --221 + j*(-203) --274 + j*(106) --42 + j*(234) -100 + j*(119) -87 + j*(26) -66 + j*(-14) -21 + j*(-45) --20 + j*(-9) -13 + j*(8) -4 + j*(-40) --59 + j*(-20) --49 + j*(38) --25 + j*(42) --22 + j*(71) -52 + j*(76) -53 + j*(-28) --86 + j*(-1) --26 + j*(194) -226 + j*(132) -187 + j*(-146) --77 + j*(-126) --53 + j*(110) -164 + j*(88) -166 + j*(-105) -30 + j*(-148) --29 + j*(-98) --57 + j*(-61) --66 + j*(14) -28 + j*(76) -149 + j*(-6) -115 + j*(-182) --88 + j*(-221) --185 + j*(-33) --21 + j*(79) -82 + j*(-96) --125 + j*(-214) --287 + j*(-10) --146 + j*(173) --12 + j*(116) --25 + j*(76) -11 + j*(93) -31 + j*(28) --45 + j*(43) -14 + j*(156) -173 + j*(86) -139 + j*(-89) -6 + j*(-100) --23 + j*(-38) --27 + j*(-8) -13 + j*(44) -117 + j*(-16) -51 + j*(-180) --146 + j*(-136) --134 + j*(37) --23 + j*(21) --78 + j*(-34) --112 + j*(47) --48 + j*(56) --108 + j*(28) --144 + j*(182) -54 + j*(279) -195 + j*(128) -129 + j*(27) -136 + j*(62) -218 + j*(-19) -161 + j*(-156) -49 + j*(-178) --12 + j*(-179) --121 + j*(-172) --220 + j*(-45) --171 + j*(123) --26 + j*(193) -110 + j*(132) -129 + j*(3) -39 + j*(-29) -65 + j*(55) -211 + j*(-35) -109 + j*(-274) --185 + j*(-220) --183 + j*(54) -26 + j*(59) --7 + j*(-98) --143 + j*(-27) --61 + j*(94) -26 + j*(10) --83 + j*(-47) --158 + j*(103) --2 + j*(258) -251 + j*(173) -300 + j*(-131) -28 + j*(-305) --199 + j*(-117) --73 + j*(78) -47 + j*(-50) --134 + j*(-120) --199 + j*(110) -38 + j*(192) -126 + j*(-15) --35 + j*(-98) --124 + j*(2) --126 + j*(100) --49 + j*(239) -209 + j*(235) -294 + j*(-68) -13 + j*(-176) --31 + j*(79) -262 + j*(23) -144 + j*(-357) --298 + j*(-252) --250 + j*(172) -72 + j*(168) -68 + j*(1) -73 + j*(57) -232 + j*(-107) --36 + j*(-400) --446 + j*(-110) --196 + j*(342) -204 + j*(129) --45 + j*(-166) --267 + j*(185) -194 + j*(424) -521 + j*(-70) -105 + j*(-478) --304 + j*(-208) --165 + j*(102) -0 + j*(15) --111 + j*(-33) --99 + j*(129) -104 + j*(97) -68 + j*(-135) --190 + j*(-107) --194 + j*(148) -14 + j*(179) -18 + j*(48) --71 + j*(122) -74 + j*(238) -245 + j*(97) -179 + j*(-89) -52 + j*(-107) --18 + j*(-81) --87 + j*(2) --12 + j*(144) -167 + j*(89) -122 + j*(-79) --1 + j*(-8) -138 + j*(82) -232 + j*(-118) -33 + j*(-228) --41 + j*(-73) -85 + j*(-91) --19 + j*(-235) --194 + j*(-97) --62 + j*(70) -66 + j*(-56) --55 + j*(-144) --111 + j*(-49) --57 + j*(-36) --92 + j*(-65) --105 + j*(-19) --88 + j*(-44) --190 + j*(-34) --196 + j*(132) --33 + j*(165) --22 + j*(61) --68 + j*(141) -124 + j*(167) -168 + j*(-108) --149 + j*(-180) --244 + j*(127) --2 + j*(221) -33 + j*(65) --71 + j*(139) -95 + j*(257) -263 + j*(78) -151 + j*(-98) -33 + j*(-74) -5 + j*(-63) --97 + j*(-25) --93 + j*(167) -140 + j*(245) -302 + j*(45) -200 + j*(-151) -46 + j*(-136) -48 + j*(-49) -122 + j*(-85) -79 + j*(-211) --98 + j*(-222) --182 + j*(-57) --70 + j*(57) -24 + j*(-21) --59 + j*(-98) --161 + j*(4) --69 + j*(160) -134 + j*(116) -154 + j*(-108) --57 + j*(-182) --161 + j*(-10) --42 + j*(93) -23 + j*(33) -18 + j*(42) -133 + j*(21) -133 + j*(-211) --172 + j*(-284) --332 + j*(1) --152 + j*(195) --28 + j*(141) --17 + j*(161) -130 + j*(177) -220 + j*(-8) -100 + j*(-139) -10 + j*(-124) --48 + j*(-148) --190 + j*(-85) --171 + j*(121) -27 + j*(141) -56 + j*(-9) --40 + j*(-22) --37 + j*(16) --66 + j*(1) --113 + j*(91) -0 + j*(174) -98 + j*(89) -57 + j*(23) -44 + j*(35) -30 + j*(5) --23 + j*(73) -120 + j*(161) -271 + j*(-38) -64 + j*(-243) --151 + j*(-73) --24 + j*(100) -72 + j*(12) -13 + j*(2) -74 + j*(50) -113 + j*(-50) -20 + j*(-53) -93 + j*(24) -184 + j*(-129) --1 + j*(-242) --82 + j*(-81) -67 + j*(-92) --29 + j*(-284) --260 + j*(-185) --206 + j*(-7) --161 + j*(-64) --305 + j*(-4) --243 + j*(209) --74 + j*(191) --119 + j*(148) --81 + j*(298) -144 + j*(272) -154 + j*(89) -76 + j*(119) -211 + j*(135) -238 + j*(-69) -45 + j*(-116) -28 + j*(28) -146 + j*(1) -110 + j*(-107) -45 + j*(-105) -16 + j*(-117) --69 + j*(-81) --28 + j*(48) -132 + j*(-17) -42 + j*(-207) --167 + j*(-116) --84 + j*(81) -78 + j*(-4) --19 + j*(-136) --136 + j*(-39) --55 + j*(69) -43 + j*(12) -22 + j*(-86) --69 + j*(-117) --155 + j*(-61) --162 + j*(35) --115 + j*(83) --90 + j*(102) --52 + j*(128) --16 + j*(120) --25 + j*(138) -55 + j*(226) -257 + j*(161) -288 + j*(-102) -76 + j*(-227) --66 + j*(-138) --85 + j*(-68) --132 + j*(-14) --106 + j*(112) -21 + j*(136) -40 + j*(70) -32 + j*(154) -274 + j*(192) -470 + j*(-161) -147 + j*(-558) --358 + j*(-407) --404 + j*(30) --165 + j*(161) --110 + j*(119) --52 + j*(228) -209 + j*(174) -204 + j*(-175) --187 + j*(-217) --269 + j*(175) -78 + j*(296) -209 + j*(49) -89 + j*(-22) -134 + j*(-6) -108 + j*(-174) --145 + j*(-147) --117 + j*(135) -160 + j*(94) -94 + j*(-165) --141 + j*(-80) --43 + j*(127) -132 + j*(31) -54 + j*(-102) --30 + j*(-47) -19 + j*(-6) -48 + j*(-57) -17 + j*(-117) --84 + j*(-141) --181 + j*(-30) --98 + j*(112) -36 + j*(63) -11 + j*(-26) --16 + j*(-16) --29 + j*(-71) --196 + j*(-40) --182 + j*(252) -190 + j*(307) -325 + j*(-54) -77 + j*(-206) -13 + j*(-109) -13 + j*(-216) --254 + j*(-208) --281 + j*(120) -9 + j*(128) --92 + j*(-108) --335 + j*(128) --39 + j*(413) -235 + j*(158) -40 + j*(-4) -47 + j*(185) -272 + j*(43) -58 + j*(-199) --151 + j*(68) -185 + j*(223) -320 + j*(-168) --80 + j*(-320) --244 + j*(13) --34 + j*(158) -46 + j*(89) -90 + j*(115) -222 + j*(21) -141 + j*(-165) --11 + j*(-110) -69 + j*(-47) -57 + j*(-207) --177 + j*(-183) --182 + j*(69) -19 + j*(83) -4 + j*(-45) --62 + j*(29) -73 + j*(46) -56 + j*(-146) --194 + j*(-108) --160 + j*(185) -148 + j*(170) -151 + j*(-126) --126 + j*(-132) --126 + j*(131) -123 + j*(138) -142 + j*(-78) --23 + j*(-88) -12 + j*(37) -146 + j*(-54) -37 + j*(-241) --188 + j*(-173) --185 + j*(35) --38 + j*(55) --45 + j*(-38) --124 + j*(16) --33 + j*(112) -83 + j*(-2) --41 + j*(-153) --229 + j*(-45) --171 + j*(152) --30 + j*(144) --42 + j*(91) --32 + j*(158) -83 + j*(134) -56 + j*(16) --47 + j*(80) -69 + j*(199) -236 + j*(71) -161 + j*(-123) --4 + j*(-136) --93 + j*(-64) --148 + j*(62) --47 + j*(245) -218 + j*(224) -298 + j*(-30) -145 + j*(-163) -47 + j*(-138) --21 + j*(-137) --120 + j*(-38) --23 + j*(128) -176 + j*(43) -117 + j*(-156) --56 + j*(-127) --53 + j*(-14) --11 + j*(-1) -14 + j*(35) -124 + j*(-1) -84 + j*(-180) --141 + j*(-144) --107 + j*(107) -157 + j*(79) -155 + j*(-175) --37 + j*(-204) --59 + j*(-121) --61 + j*(-178) --214 + j*(-185) --306 + j*(-16) --241 + j*(144) --115 + j*(222) -52 + j*(216) -165 + j*(67) -101 + j*(-112) --72 + j*(-145) --185 + j*(-23) --122 + j*(134) -55 + j*(108) -33 + j*(-105) --250 + j*(-77) --265 + j*(286) -128 + j*(386) -296 + j*(48) -64 + j*(-122) --53 + j*(13) -15 + j*(66) -23 + j*(66) -108 + j*(94) -180 + j*(-81) --65 + j*(-205) --232 + j*(86) -78 + j*(267) -239 + j*(-42) --71 + j*(-153) --117 + j*(177) -238 + j*(168) -198 + j*(-204) --176 + j*(-141) --97 + j*(228) -262 + j*(150) -208 + j*(-185) --86 + j*(-157) --82 + j*(98) -142 + j*(136) -242 + j*(-37) -164 + j*(-181) -35 + j*(-193) -2 + j*(-112) -82 + j*(-119) -57 + j*(-270) --162 + j*(-302) --274 + j*(-95) --132 + j*(29) --64 + j*(-79) --197 + j*(-99) --213 + j*(50) --98 + j*(53) --172 + j*(-28) --287 + j*(146) --75 + j*(344) -168 + j*(168) -29 + j*(-42) --130 + j*(121) -88 + j*(276) -290 + j*(46) -116 + j*(-192) --108 + j*(-100) --81 + j*(66) -20 + j*(63) -8 + j*(11) --29 + j*(52) -40 + j*(115) -158 + j*(41) -110 + j*(-136) --104 + j*(-132) --139 + j*(93) -78 + j*(148) -141 + j*(-59) --54 + j*(-121) --123 + j*(51) -1 + j*(128) -66 + j*(78) -93 + j*(68) -163 + j*(-1) -104 + j*(-146) --76 + j*(-124) --93 + j*(61) -79 + j*(119) -188 + j*(-23) -113 + j*(-179) --43 + j*(-187) --100 + j*(-78) --45 + j*(-51) --98 + j*(-113) --233 + j*(1) --123 + j*(232) -156 + j*(174) -148 + j*(-90) --66 + j*(-91) --35 + j*(91) -155 + j*(33) -121 + j*(-197) --119 + j*(-256) --310 + j*(-78) --269 + j*(197) -3 + j*(300) -182 + j*(91) -19 + j*(-75) --105 + j*(106) -130 + j*(225) -284 + j*(-35) -54 + j*(-224) --133 + j*(-47) --6 + j*(124) -160 + j*(51) -171 + j*(-109) -57 + j*(-223) --130 + j*(-194) --180 + j*(4) --11 + j*(92) -74 + j*(-50) --52 + j*(-118) --97 + j*(-11) --3 + j*(7) -8 + j*(-91) --86 + j*(-139) --194 + j*(-109) --279 + j*(10) --231 + j*(179) --83 + j*(216) --47 + j*(160) --45 + j*(217) -106 + j*(235) -167 + j*(57) --2 + j*(1) --26 + j*(185) -186 + j*(215) -257 + j*(21) -141 + j*(-59) -119 + j*(-13) -165 + j*(-59) -110 + j*(-144) -8 + j*(-139) --33 + j*(-65) -11 + j*(-12) -63 + j*(-57) --11 + j*(-122) --100 + j*(-14) -40 + j*(100) -182 + j*(-69) --8 + j*(-233) --179 + j*(-41) -19 + j*(117) -161 + j*(-88) --35 + j*(-218) --136 + j*(-60) --17 + j*(-28) --75 + j*(-149) --241 + j*(-43) --153 + j*(168) -45 + j*(142) -80 + j*(20) -69 + j*(-28) -76 + j*(-134) --96 + j*(-247) --325 + j*(-105) --283 + j*(164) --85 + j*(204) --66 + j*(121) --98 + j*(215) -92 + j*(301) -265 + j*(112) -143 + j*(-83) -3 + j*(-4) -103 + j*(76) -180 + j*(-63) -59 + j*(-177) --62 + j*(-136) --111 + j*(-74) --144 + j*(11) --81 + j*(103) -1 + j*(78) --28 + j*(57) -13 + j*(127) -128 + j*(42) --3 + j*(-99) --172 + j*(89) -55 + j*(308) -307 + j*(102) -168 + j*(-109) -77 + j*(-8) -207 + j*(-42) -105 + j*(-216) --57 + j*(-90) -122 + j*(7) -168 + j*(-257) --159 + j*(-298) --193 + j*(23) -97 + j*(0) -6 + j*(-298) --320 + j*(-202) --291 + j*(93) --113 + j*(110) --132 + j*(59) --149 + j*(163) --18 + j*(245) -150 + j*(180) -192 + j*(-21) --12 + j*(-139) --167 + j*(93) -133 + j*(296) -422 + j*(-64) -78 + j*(-441) --328 + j*(-182) --164 + j*(155) -32 + j*(40) --94 + j*(-28) --88 + j*(132) -64 + j*(98) -8 + j*(21) -30 + j*(139) -245 + j*(49) -146 + j*(-260) --206 + j*(-195) --180 + j*(150) -134 + j*(155) -177 + j*(-130) --66 + j*(-232) --235 + j*(-58) --152 + j*(147) -47 + j*(132) -57 + j*(-49) --119 + j*(-60) --140 + j*(104) --33 + j*(127) --69 + j*(110) --46 + j*(278) -240 + j*(312) -383 + j*(20) -192 + j*(-167) -70 + j*(-82) -132 + j*(-64) -102 + j*(-156) -2 + j*(-146) --12 + j*(-86) -6 + j*(-78) -10 + j*(-89) -1 + j*(-121) --66 + j*(-136) --112 + j*(-70) --74 + j*(-28) --65 + j*(-53) --93 + j*(-38) --75 + j*(-33) --134 + j*(-76) --257 + j*(40) --152 + j*(264) -122 + j*(228) -159 + j*(-25) --31 + j*(-98) --112 + j*(28) --53 + j*(109) -6 + j*(115) -55 + j*(113) -119 + j*(81) -160 + j*(-12) -98 + j*(-134) --69 + j*(-132) --108 + j*(42) -71 + j*(84) -102 + j*(-123) --149 + j*(-164) --233 + j*(99) --30 + j*(226) -82 + j*(144) -124 + j*(140) -285 + j*(53) -253 + j*(-241) --65 + j*(-312) --187 + j*(-81) --78 + j*(-13) --146 + j*(-58) --225 + j*(144) -30 + j*(315) -274 + j*(113) -185 + j*(-124) -39 + j*(-122) -31 + j*(-100) --21 + j*(-143) --119 + j*(-92) --108 + j*(5) --59 + j*(8) --90 + j*(-4) --119 + j*(73) --38 + j*(153) -69 + j*(119) -79 + j*(35) -44 + j*(34) -98 + j*(56) -162 + j*(-49) -58 + j*(-182) --121 + j*(-129) --134 + j*(50) -6 + j*(117) -101 + j*(33) -76 + j*(-61) -10 + j*(-74) --4 + j*(-46) -1 + j*(-69) --63 + j*(-79) --99 + j*(14) -19 + j*(67) -86 + j*(-82) --101 + j*(-184) --262 + j*(23) --74 + j*(246) -199 + j*(108) -130 + j*(-200) --197 + j*(-220) --322 + j*(87) --86 + j*(292) -134 + j*(148) -47 + j*(-25) --66 + j*(71) -64 + j*(151) -130 + j*(-6) --42 + j*(-47) --55 + j*(150) -165 + j*(156) -183 + j*(-57) -16 + j*(-71) -38 + j*(48) -134 + j*(-11) -57 + j*(-99) --16 + j*(-20) -64 + j*(59) -183 + j*(12) -243 + j*(-139) -146 + j*(-344) --136 + j*(-390) --310 + j*(-160) --190 + j*(20) --101 + j*(-61) --244 + j*(-89) --314 + j*(119) --135 + j*(274) -37 + j*(193) -9 + j*(93) --30 + j*(167) -136 + j*(244) -330 + j*(52) -206 + j*(-245) --100 + j*(-232) --156 + j*(-1) --20 + j*(57) --2 + j*(-8) --21 + j*(8) -9 + j*(-23) --84 + j*(-71) --172 + j*(70) --40 + j*(197) -71 + j*(134) -69 + j*(122) -204 + j*(131) -289 + j*(-105) -48 + j*(-267) --117 + j*(-80) -29 + j*(9) -35 + j*(-146) --147 + j*(-115) --127 + j*(57) --21 + j*(53) --33 + j*(38) -35 + j*(74) -91 + j*(-54) --83 + j*(-115) --143 + j*(86) -59 + j*(139) -90 + j*(-30) --27 + j*(-8) -72 + j*(67) -134 + j*(-110) --86 + j*(-178) --147 + j*(43) -63 + j*(65) -36 + j*(-163) --241 + j*(-127) --261 + j*(175) --10 + j*(271) -105 + j*(127) -33 + j*(82) -76 + j*(185) -282 + j*(139) -342 + j*(-134) -117 + j*(-313) --91 + j*(-217) --93 + j*(-85) --62 + j*(-66) --66 + j*(-48) --45 + j*(-54) --103 + j*(-93) --198 + j*(10) --96 + j*(158) -62 + j*(83) --5 + j*(-36) --83 + j*(56) -40 + j*(118) -115 + j*(-21) --5 + j*(-117) --124 + j*(-46) --124 + j*(76) --24 + j*(152) -101 + j*(85) -59 + j*(-54) --82 + j*(-16) --40 + j*(128) -96 + j*(98) -89 + j*(8) -78 + j*(14) -117 + j*(-49) -11 + j*(-134) --95 + j*(-16) -24 + j*(91) -124 + j*(-26) -34 + j*(-121) --38 + j*(-86) --65 + j*(-70) --132 + j*(-6) --73 + j*(136) -105 + j*(129) -165 + j*(-20) -114 + j*(-127) -27 + j*(-206) --149 + j*(-214) --279 + j*(-35) --199 + j*(165) --30 + j*(222) -127 + j*(180) -237 + j*(3) -117 + j*(-216) --130 + j*(-172) --134 + j*(24) --23 + j*(24) --66 + j*(-16) --55 + j*(66) -30 + j*(5) --110 + j*(-68) --191 + j*(171) -123 + j*(295) -298 + j*(-30) -11 + j*(-223) --153 + j*(-2) -4 + j*(105) -43 + j*(1) --23 + j*(31) -62 + j*(81) -114 + j*(-18) -42 + j*(-70) -21 + j*(-55) --17 + j*(-88) --118 + j*(-25) --51 + j*(135) -152 + j*(98) -173 + j*(-116) --1 + j*(-206) --134 + j*(-121) --135 + j*(-4) --72 + j*(30) --74 + j*(0) --143 + j*(57) --77 + j*(211) -144 + j*(200) -202 + j*(-10) -59 + j*(-81) -58 + j*(10) -178 + j*(-93) -22 + j*(-322) --337 + j*(-206) --330 + j*(221) -78 + j*(327) -239 + j*(-14) --35 + j*(-155) --123 + j*(98) -151 + j*(136) -168 + j*(-165) --141 + j*(-185) --166 + j*(93) -47 + j*(113) -43 + j*(-6) -30 + j*(49) -165 + j*(-33) -17 + j*(-255) --269 + j*(-81) --86 + j*(231) -225 + j*(40) -30 + j*(-259) --252 + j*(-91) --139 + j*(146) -13 + j*(98) -14 + j*(58) -77 + j*(35) -42 + j*(-102) --147 + j*(-42) --55 + j*(191) -230 + j*(76) -115 + j*(-262) --256 + j*(-185) --249 + j*(168) --23 + j*(28) -142 + j*(89) -243 + j*(-152) --11 + j*(-301) --160 + j*(-95) --9 + j*(-13) --18 + j*(-156) --180 + j*(-100) --137 + j*(49) --59 + j*(32) --93 + j*(57) -9 + j*(139) -139 + j*(30) -85 + j*(-95) -49 + j*(-113) --1 + j*(-236) --292 + j*(-232) --390 + j*(163) -18 + j*(347) -232 + j*(-16) --69 + j*(-199) --178 + j*(31) --9 + j*(29) --153 + j*(-123) --350 + j*(132) --78 + j*(395) -177 + j*(175) --3 + j*(17) --54 + j*(233) -233 + j*(250) -274 + j*(-47) -47 + j*(-99) -62 + j*(39) -161 + j*(-92) --80 + j*(-226) --301 + j*(77) --18 + j*(404) -385 + j*(230) -369 + j*(-156) -106 + j*(-264) --22 + j*(-159) --18 + j*(-98) --25 + j*(-91) --62 + j*(-67) --71 + j*(3) -14 + j*(64) -128 + j*(-19) -71 + j*(-185) --119 + j*(-175) --159 + j*(-13) --60 + j*(39) --55 + j*(-1) --75 + j*(60) -33 + j*(105) -115 + j*(1) -66 + j*(-100) -3 + j*(-122) --59 + j*(-150) --186 + j*(-126) --264 + j*(36) --168 + j*(209) -22 + j*(231) -126 + j*(107) -83 + j*(4) -36 + j*(27) -107 + j*(28) -112 + j*(-110) --60 + j*(-147) --120 + j*(21) -26 + j*(76) -58 + j*(-45) --23 + j*(-40) -44 + j*(-8) -48 + j*(-170) --195 + j*(-199) --287 + j*(54) --105 + j*(174) --40 + j*(91) --74 + j*(122) -21 + j*(158) -40 + j*(59) --60 + j*(115) -76 + j*(275) -334 + j*(137) -289 + j*(-160) -68 + j*(-228) --31 + j*(-156) --88 + j*(-124) --161 + j*(-33) --124 + j*(107) -8 + j*(153) -107 + j*(76) -85 + j*(-28) --11 + j*(-13) -36 + j*(100) -209 + j*(28) -150 + j*(-202) --91 + j*(-184) --93 + j*(16) -47 + j*(-1) --6 + j*(-98) --74 + j*(-21) -4 + j*(15) -9 + j*(-45) --18 + j*(-18) -45 + j*(-42) --28 + j*(-154) --188 + j*(-57) --95 + j*(119) -54 + j*(37) --26 + j*(-59) --64 + j*(36) -48 + j*(21) -4 + j*(-108) --123 + j*(-68) --115 + j*(13) --122 + j*(18) --150 + j*(101) --64 + j*(182) -11 + j*(168) -74 + j*(197) -255 + j*(128) -258 + j*(-156) --20 + j*(-245) --132 + j*(-64) --83 + j*(-25) --188 + j*(30) --97 + j*(302) -292 + j*(246) -298 + j*(-159) --21 + j*(-179) -32 + j*(19) -153 + j*(-161) --119 + j*(-269) --227 + j*(11) -1 + j*(71) --40 + j*(-97) --175 + j*(52) -53 + j*(170) -153 + j*(-105) --145 + j*(-195) --250 + j*(85) --49 + j*(207) -48 + j*(129) -69 + j*(92) -109 + j*(19) -41 + j*(-40) -16 + j*(28) -91 + j*(10) -21 + j*(-59) --27 + j*(63) -158 + j*(100) -209 + j*(-114) -35 + j*(-167) -47 + j*(-66) -111 + j*(-199) --112 + j*(-295) --257 + j*(-64) --81 + j*(86) -22 + j*(-27) --33 + j*(-78) --40 + j*(-95) --135 + j*(-163) --308 + j*(-43) --243 + j*(182) --76 + j*(193) --74 + j*(161) --16 + j*(262) -194 + j*(226) -250 + j*(6) -122 + j*(-113) -16 + j*(-117) --87 + j*(-83) --140 + j*(62) --11 + j*(180) -116 + j*(110) -89 + j*(40) -112 + j*(82) -233 + j*(13) -198 + j*(-182) --1 + j*(-221) --87 + j*(-75) -7 + j*(4) -69 + j*(-75) --1 + j*(-138) --55 + j*(-95) --35 + j*(-101) --127 + j*(-163) --291 + j*(-27) --199 + j*(238) -83 + j*(233) -132 + j*(16) --4 + j*(-6) -42 + j*(98) -173 + j*(21) -136 + j*(-142) -4 + j*(-189) --103 + j*(-150) --156 + j*(-56) --114 + j*(25) --72 + j*(-2) --146 + j*(-1) --158 + j*(125) --50 + j*(185) -4 + j*(173) -88 + j*(221) -277 + j*(117) -223 + j*(-158) --43 + j*(-142) -3 + j*(74) -201 + j*(-54) -4 + j*(-277) --254 + j*(-63) --64 + j*(196) -165 + j*(43) -50 + j*(-132) --64 + j*(-62) --34 + j*(-21) --73 + j*(-23) --63 + j*(88) -105 + j*(88) -138 + j*(-120) --75 + j*(-207) --221 + j*(-44) --150 + j*(121) --31 + j*(136) -4 + j*(95) --1 + j*(103) -50 + j*(145) -151 + j*(125) -222 + j*(25) -218 + j*(-111) -110 + j*(-235) --87 + j*(-225) --169 + j*(-39) --33 + j*(73) -58 + j*(-28) --32 + j*(-81) --56 + j*(-4) -0 + j*(-13) --52 + j*(-40) --47 + j*(54) -88 + j*(6) --13 + j*(-171) --248 + j*(-30) --103 + j*(257) -195 + j*(141) -110 + j*(-98) --19 + j*(-1) -159 + j*(16) -120 + j*(-291) --305 + j*(-276) --378 + j*(201) -63 + j*(371) -286 + j*(28) -67 + j*(-182) --76 + j*(-67) --17 + j*(-21) --61 + j*(-85) --170 + j*(4) --101 + j*(160) -56 + j*(147) -92 + j*(47) -78 + j*(16) -103 + j*(-33) -47 + j*(-131) --84 + j*(-116) --113 + j*(-16) --83 + j*(1) --139 + j*(10) --166 + j*(136) --43 + j*(240) -93 + j*(202) -138 + j*(125) -150 + j*(73) -153 + j*(25) -153 + j*(-23) -118 + j*(-97) --18 + j*(-105) --68 + j*(83) -180 + j*(184) -353 + j*(-104) -77 + j*(-334) --151 + j*(-103) -63 + j*(66) -168 + j*(-168) --89 + j*(-233) --119 + j*(25) -132 + j*(16) -107 + j*(-228) --86 + j*(-214) --54 + j*(-138) --92 + j*(-265) --349 + j*(-207) --356 + j*(107) --93 + j*(160) --73 + j*(-28) --248 + j*(10) --212 + j*(209) --37 + j*(228) -18 + j*(128) --33 + j*(85) --90 + j*(137) --46 + j*(281) -199 + j*(336) -417 + j*(77) -261 + j*(-259) --77 + j*(-247) --156 + j*(1) --24 + j*(88) -17 + j*(42) -16 + j*(64) -92 + j*(48) -74 + j*(-57) --51 + j*(-31) --7 + j*(107) -146 + j*(42) -68 + j*(-126) --114 + j*(-33) --16 + j*(158) -170 + j*(69) -87 + j*(-78) --1 + j*(31) -176 + j*(82) -247 + j*(-149) -19 + j*(-266) --98 + j*(-95) -27 + j*(-35) -33 + j*(-168) --127 + j*(-173) --180 + j*(-40) --136 + j*(45) --74 + j*(109) -67 + j*(114) -138 + j*(-57) --23 + j*(-173) --140 + j*(-45) --43 + j*(23) --66 + j*(-90) --259 + j*(13) --144 + j*(330) -278 + j*(287) -363 + j*(-161) --17 + j*(-372) --299 + j*(-127) --216 + j*(142) --33 + j*(185) -62 + j*(124) -99 + j*(53) -91 + j*(-22) -33 + j*(-68) --33 + j*(-50) --51 + j*(11) -7 + j*(47) -59 + j*(-15) --10 + j*(-90) --110 + j*(-23) --59 + j*(87) -34 + j*(46) --17 + j*(-21) --74 + j*(53) -9 + j*(121) -81 + j*(61) -57 + j*(22) -82 + j*(31) -119 + j*(-49) -18 + j*(-129) --86 + j*(-42) --18 + j*(55) -60 + j*(-11) --16 + j*(-70) --66 + j*(14) -22 + j*(47) -23 + j*(-51) --113 + j*(-11) --48 + j*(196) -238 + j*(147) -247 + j*(-192) --85 + j*(-257) --155 + j*(30) -103 + j*(41) -40 + j*(-253) --333 + j*(-172) --313 + j*(243) -45 + j*(299) -109 + j*(74) --7 + j*(95) -122 + j*(183) -224 + j*(11) -69 + j*(-73) -57 + j*(95) -303 + j*(52) -310 + j*(-268) -7 + j*(-387) --173 + j*(-211) --130 + j*(-76) --92 + j*(-74) --115 + j*(-60) --124 + j*(-13) --91 + j*(41) --10 + j*(51) -42 + j*(-41) --47 + j*(-139) --182 + j*(-78) --173 + j*(54) --92 + j*(66) --122 + j*(40) --153 + j*(150) --4 + j*(240) -147 + j*(111) -57 + j*(-50) --78 + j*(25) -3 + j*(144) -118 + j*(59) -32 + j*(-44) --53 + j*(49) -57 + j*(134) -166 + j*(28) -100 + j*(-100) --23 + j*(-94) --69 + j*(-5) --24 + j*(75) -73 + j*(71) -105 + j*(-28) -19 + j*(-87) --48 + j*(-28) --14 + j*(33) -34 + j*(14) -28 + j*(-35) --40 + j*(-55) --118 + j*(28) --57 + j*(181) -138 + j*(190) -226 + j*(35) -182 + j*(-69) -153 + j*(-136) -42 + j*(-231) --151 + j*(-138) --90 + j*(93) -134 + j*(37) -58 + j*(-165) --120 + j*(-41) -66 + j*(122) -249 + j*(-115) -25 + j*(-331) --183 + j*(-188) --133 + j*(-76) --165 + j*(-93) --202 + j*(42) --27 + j*(93) --12 + j*(-100) --242 + j*(-66) --185 + j*(194) -54 + j*(130) --50 + j*(-53) --193 + j*(125) -37 + j*(274) -191 + j*(54) -31 + j*(-66) --7 + j*(38) -71 + j*(-16) --44 + j*(-88) --101 + j*(44) -20 + j*(53) --57 + j*(-65) --210 + j*(97) --16 + j*(304) -215 + j*(141) -97 + j*(-46) --6 + j*(60) -120 + j*(99) -136 + j*(-38) -18 + j*(-38) -42 + j*(48) -107 + j*(1) -57 + j*(-47) -26 + j*(5) -81 + j*(33) -141 + j*(0) -173 + j*(-95) -95 + j*(-210) --70 + j*(-194) --105 + j*(-44) -3 + j*(1) -30 + j*(-78) --32 + j*(-98) --53 + j*(-66) --62 + j*(-49) --61 + j*(-18) --31 + j*(-13) --39 + j*(-23) --13 + j*(19) -91 + j*(-51) --1 + j*(-260) --320 + j*(-216) --397 + j*(143) --115 + j*(337) -115 + j*(214) -139 + j*(40) -49 + j*(-75) --118 + j*(-44) --129 + j*(173) -124 + j*(238) -250 + j*(3) -105 + j*(-143) -11 + j*(-124) --68 + j*(-156) --247 + j*(-36) --146 + j*(260) -207 + j*(206) -195 + j*(-151) --132 + j*(-167) --176 + j*(112) -36 + j*(192) -151 + j*(66) -110 + j*(-78) --63 + j*(-106) --148 + j*(112) -112 + j*(264) -325 + j*(5) -118 + j*(-218) --31 + j*(-66) -116 + j*(-28) -83 + j*(-211) --91 + j*(-182) --86 + j*(-112) --183 + j*(-161) --344 + j*(81) --52 + j*(357) -272 + j*(78) -11 + j*(-212) --203 + j*(57) -82 + j*(208) -194 + j*(-78) --54 + j*(-166) --121 + j*(7) --37 + j*(44) --34 + j*(38) -3 + j*(48) --25 + j*(-1) --94 + j*(120) -136 + j*(245) -339 + j*(-54) -30 + j*(-305) --209 + j*(-25) -49 + j*(156) -170 + j*(-87) --35 + j*(-169) --88 + j*(-43) --66 + j*(-39) --115 + j*(36) -23 + j*(114) -80 + j*(-83) --192 + j*(-81) --143 + j*(287) -305 + j*(229) -269 + j*(-241) --158 + j*(-226) --134 + j*(123) -133 + j*(91) -112 + j*(-100) -21 + j*(-112) --12 + j*(-141) --151 + j*(-126) --176 + j*(70) -25 + j*(135) -128 + j*(-49) --12 + j*(-217) --269 + j*(-181) --410 + j*(129) --139 + j*(447) -255 + j*(280) -152 + j*(-53) --63 + j*(101) -237 + j*(246) -395 + j*(-192) --105 + j*(-402) --348 + j*(83) -75 + j*(325) -288 + j*(1) -97 + j*(-154) -42 + j*(-95) -8 + j*(-169) --168 + j*(-93) --78 + j*(130) -153 + j*(20) -26 + j*(-214) --209 + j*(-102) --149 + j*(105) --20 + j*(105) -6 + j*(71) -43 + j*(59) -47 + j*(8) -25 + j*(18) -91 + j*(8) -78 + j*(-132) --117 + j*(-150) --182 + j*(47) --35 + j*(133) -28 + j*(59) -6 + j*(62) -74 + j*(63) -69 + j*(-37) --41 + j*(-14) -18 + j*(109) -173 + j*(21) -81 + j*(-160) --103 + j*(-80) --34 + j*(78) -88 + j*(11) -18 + j*(-66) --6 + j*(19) -110 + j*(-4) -63 + j*(-157) --106 + j*(-113) --64 + j*(42) -68 + j*(-10) -10 + j*(-130) --93 + j*(-92) --92 + j*(-38) --109 + j*(-23) --107 + j*(44) --27 + j*(44) --62 + j*(-31) --153 + j*(49) --58 + j*(158) -23 + j*(69) --84 + j*(64) --25 + j*(244) -223 + j*(180) -191 + j*(-71) -10 + j*(-33) -115 + j*(78) -214 + j*(-107) -6 + j*(-233) --123 + j*(-74) --34 + j*(-1) --45 + j*(-49) --81 + j*(33) -39 + j*(55) -24 + j*(-92) --163 + j*(-40) --100 + j*(196) -172 + j*(156) -171 + j*(-119) --78 + j*(-161) --156 + j*(51) -6 + j*(148) -101 + j*(45) -38 + j*(-13) -35 + j*(58) -165 + j*(34) -175 + j*(-161) --36 + j*(-250) --189 + j*(-88) --101 + j*(69) -21 + j*(22) --23 + j*(-78) --138 + j*(-33) --126 + j*(103) --8 + j*(134) -12 + j*(66) --43 + j*(127) -112 + j*(260) -383 + j*(100) -330 + j*(-258) -23 + j*(-337) --91 + j*(-199) --110 + j*(-185) --264 + j*(-117) --245 + j*(149) -30 + j*(205) -112 + j*(-11) --33 + j*(-68) --39 + j*(21) -15 + j*(-33) --98 + j*(-83) --180 + j*(64) --58 + j*(203) -113 + j*(162) -166 + j*(11) -74 + j*(-98) --35 + j*(-45) -30 + j*(42) -125 + j*(-70) --13 + j*(-211) --194 + j*(-110) --166 + j*(54) --81 + j*(71) --74 + j*(62) --68 + j*(71) --101 + j*(92) --91 + j*(233) -141 + j*(305) -310 + j*(66) -131 + j*(-126) -1 + j*(6) -140 + j*(49) -129 + j*(-116) --45 + j*(-67) -49 + j*(110) -257 + j*(-18) -165 + j*(-269) --75 + j*(-278) --187 + j*(-138) --194 + j*(9) --90 + j*(130) -77 + j*(91) -92 + j*(-62) --18 + j*(-95) --43 + j*(-37) --19 + j*(-49) --71 + j*(-74) --126 + j*(-21) --115 + j*(54) --66 + j*(91) --29 + j*(91) --13 + j*(107) -62 + j*(142) -178 + j*(54) -115 + j*(-120) --73 + j*(-76) --18 + j*(118) -209 + j*(47) -165 + j*(-208) --64 + j*(-236) --146 + j*(-114) --171 + j*(-52) --197 + j*(86) --19 + j*(215) -181 + j*(56) -65 + j*(-170) --143 + j*(-106) --127 + j*(49) --51 + j*(53) --61 + j*(43) --43 + j*(68) --45 + j*(40) --124 + j*(97) --59 + j*(291) -234 + j*(317) -419 + j*(34) -269 + j*(-258) -0 + j*(-274) --101 + j*(-117) --46 + j*(-37) --21 + j*(-72) --90 + j*(-83) --137 + j*(1) --93 + j*(83) --21 + j*(95) -9 + j*(76) -27 + j*(77) -75 + j*(76) -117 + j*(24) -112 + j*(-40) -88 + j*(-76) -69 + j*(-136) --57 + j*(-201) --231 + j*(-71) --143 + j*(190) -165 + j*(153) -162 + j*(-180) --190 + j*(-209) --260 + j*(144) -57 + j*(249) -159 + j*(-2) --35 + j*(-54) --25 + j*(131) -188 + j*(100) -193 + j*(-130) -9 + j*(-199) --107 + j*(-110) --122 + j*(3) --39 + j*(104) -126 + j*(49) -95 + j*(-164) --158 + j*(-164) --190 + j*(103) -61 + j*(153) -91 + j*(-58) --81 + j*(-35) -20 + j*(119) -177 + j*(-62) --69 + j*(-240) --276 + j*(49) -34 + j*(281) -285 + j*(-22) -19 + j*(-272) --194 + j*(-66) --27 + j*(69) -28 + j*(-104) --188 + j*(-129) --248 + j*(105) --57 + j*(221) -81 + j*(108) -33 + j*(-18) --84 + j*(-7) --110 + j*(110) --21 + j*(176) -41 + j*(153) -64 + j*(177) -202 + j*(193) -331 + j*(9) -216 + j*(-207) -10 + j*(-214) --82 + j*(-117) --124 + j*(-12) --60 + j*(143) -165 + j*(153) -257 + j*(-86) -69 + j*(-237) --88 + j*(-146) --94 + j*(-47) --86 + j*(23) -16 + j*(106) -173 + j*(-12) -57 + j*(-231) --211 + j*(-134) --149 + j*(158) -141 + j*(144) -181 + j*(-113) --13 + j*(-198) --105 + j*(-86) --56 + j*(-25) --36 + j*(-57) --80 + j*(-63) --96 + j*(-18) --71 + j*(-6) --88 + j*(-24) --124 + j*(11) --108 + j*(51) --127 + j*(59) --153 + j*(185) -56 + j*(325) -334 + j*(108) -181 + j*(-267) --224 + j*(-204) --241 + j*(168) -48 + j*(234) -113 + j*(47) -2 + j*(36) -62 + j*(136) -213 + j*(46) -154 + j*(-175) --127 + j*(-190) --233 + j*(129) -107 + j*(342) -432 + j*(21) -193 + j*(-389) --214 + j*(-258) --167 + j*(44) --10 + j*(-9) --145 + j*(-54) --161 + j*(165) -77 + j*(206) -124 + j*(30) -33 + j*(39) -134 + j*(86) -187 + j*(-78) -29 + j*(-138) -6 + j*(-11) -123 + j*(-55) -44 + j*(-189) --88 + j*(-116) --22 + j*(-35) -0 + j*(-133) --151 + j*(-132) --167 + j*(40) --13 + j*(62) --16 + j*(-68) --141 + j*(-30) --83 + j*(93) -20 + j*(7) --124 + j*(-78) --226 + j*(129) -3 + j*(272) -150 + j*(62) --44 + j*(-34) --73 + j*(190) -191 + j*(197) -207 + j*(-57) -29 + j*(-50) -119 + j*(46) -187 + j*(-148) --65 + j*(-232) --148 + j*(8) -50 + j*(37) --4 + j*(-137) --182 + j*(-20) --45 + j*(158) -105 + j*(30) --4 + j*(-66) --45 + j*(23) -9 + j*(13) --52 + j*(4) --19 + j*(126) -153 + j*(77) -108 + j*(-109) --53 + j*(-69) -4 + j*(52) -96 + j*(-33) -2 + j*(-112) --69 + j*(-32) --9 + j*(22) -33 + j*(-21) -0 + j*(-68) --62 + j*(-46) --46 + j*(37) -66 + j*(11) -30 + j*(-150) --177 + j*(-118) --157 + j*(100) -45 + j*(60) --61 + j*(-139) --303 + j*(23) --157 + j*(322) -144 + j*(255) -147 + j*(33) -25 + j*(8) -7 + j*(61) -13 + j*(86) -44 + j*(142) -145 + j*(150) -210 + j*(77) -241 + j*(18) -287 + j*(-81) -238 + j*(-244) -66 + j*(-323) --96 + j*(-256) --141 + j*(-104) --23 + j*(-13) -90 + j*(-146) --77 + j*(-325) --341 + j*(-188) --293 + j*(81) --135 + j*(83) --202 + j*(64) --162 + j*(275) -168 + j*(275) -245 + j*(-84) --76 + j*(-218) --229 + j*(35) --60 + j*(180) -47 + j*(89) -11 + j*(42) -16 + j*(64) -44 + j*(25) --13 + j*(-21) --99 + j*(47) --55 + j*(198) -146 + j*(237) -291 + j*(61) -218 + j*(-129) -86 + j*(-161) -35 + j*(-143) --24 + j*(-154) --101 + j*(-112) --124 + j*(-42) --135 + j*(21) --102 + j*(127) -57 + j*(161) -150 + j*(1) -18 + j*(-112) --95 + j*(-10) --21 + j*(100) -87 + j*(67) -116 + j*(-28) -54 + j*(-124) --98 + j*(-109) --133 + j*(77) -69 + j*(161) -203 + j*(-35) -54 + j*(-216) --146 + j*(-167) --224 + j*(-10) --188 + j*(171) -14 + j*(291) -250 + j*(158) -218 + j*(-100) -19 + j*(-132) --16 + j*(-2) -76 + j*(18) -112 + j*(-52) -95 + j*(-116) -40 + j*(-169) --35 + j*(-170) --69 + j*(-151) --129 + j*(-165) --239 + j*(-93) --221 + j*(59) --125 + j*(80) --156 + j*(69) --143 + j*(208) -67 + j*(241) -147 + j*(46) -19 + j*(-22) -22 + j*(44) -44 + j*(-50) --145 + j*(-43) --127 + j*(237) -229 + j*(223) -235 + j*(-165) --151 + j*(-180) --155 + j*(177) -153 + j*(168) -124 + j*(-74) --42 + j*(-8) -70 + j*(91) -132 + j*(-57) --16 + j*(-89) --14 + j*(28) -62 + j*(-24) --44 + j*(-62) --59 + j*(84) -106 + j*(90) -103 + j*(-62) --1 + j*(-36) -63 + j*(8) -52 + j*(-102) --98 + j*(-39) -11 + j*(155) -250 + j*(24) -140 + j*(-243) --105 + j*(-181) --74 + j*(-2) -33 + j*(-24) -21 + j*(-81) -16 + j*(-94) --13 + j*(-163) --137 + j*(-158) --172 + j*(-35) --105 + j*(8) --95 + j*(-8) --82 + j*(9) --61 + j*(-47) --184 + j*(-91) --302 + j*(69) --197 + j*(250) --46 + j*(255) -18 + j*(230) -116 + j*(202) -153 + j*(69) -47 + j*(14) -29 + j*(103) -125 + j*(91) -109 + j*(3) -63 + j*(23) -106 + j*(21) -71 + j*(-32) -40 + j*(49) -194 + j*(54) -204 + j*(-183) --79 + j*(-221) --124 + j*(70) -163 + j*(100) -186 + j*(-181) --60 + j*(-213) --83 + j*(-37) -16 + j*(-55) --47 + j*(-115) --82 + j*(-51) --53 + j*(-66) --161 + j*(-73) --185 + j*(126) -58 + j*(189) -151 + j*(-55) --72 + j*(-164) --196 + j*(13) --115 + j*(155) -0 + j*(219) -228 + j*(195) -358 + j*(-156) --49 + j*(-463) --512 + j*(-72) --199 + j*(486) -371 + j*(288) -278 + j*(-197) --54 + j*(-151) -15 + j*(26) -78 + j*(-95) --64 + j*(-87) -24 + j*(35) -124 + j*(-163) --172 + j*(-277) --321 + j*(49) --28 + j*(185) -27 + j*(-65) --226 + j*(-18) --119 + j*(266) -170 + j*(151) -62 + j*(-108) --163 + j*(-12) --113 + j*(191) -39 + j*(240) -192 + j*(206) -313 + j*(23) -193 + j*(-197) --11 + j*(-159) -4 + j*(-62) --11 + j*(-136) --180 + j*(-67) --119 + j*(165) -107 + j*(136) -76 + j*(-18) -13 + j*(76) -216 + j*(109) -313 + j*(-185) -30 + j*(-404) --285 + j*(-245) --296 + j*(75) --49 + j*(220) -146 + j*(54) -26 + j*(-124) --112 + j*(8) -83 + j*(111) -186 + j*(-162) --133 + j*(-306) --315 + j*(-18) --127 + j*(135) --94 + j*(33) --190 + j*(153) -16 + j*(314) -231 + j*(128) -124 + j*(-67) -6 + j*(-33) --10 + j*(6) --33 + j*(81) -122 + j*(173) -308 + j*(-51) -71 + j*(-327) --252 + j*(-132) --125 + j*(173) -107 + j*(110) -95 + j*(-14) -96 + j*(-24) -103 + j*(-139) --78 + j*(-181) --139 + j*(-2) -4 + j*(33) --23 + j*(-80) --119 + j*(13) -23 + j*(93) -81 + j*(-90) --136 + j*(-134) --177 + j*(100) -45 + j*(131) -47 + j*(-78) --180 + j*(-56) --181 + j*(211) -100 + j*(286) -260 + j*(47) -89 + j*(-166) --144 + j*(-52) --66 + j*(201) -208 + j*(168) -238 + j*(-100) -21 + j*(-173) --49 + j*(-18) -68 + j*(19) -83 + j*(-82) -11 + j*(-84) -57 + j*(-57) -86 + j*(-197) --140 + j*(-319) --407 + j*(-100) --293 + j*(264) -62 + j*(272) -123 + j*(-11) --105 + j*(-58) --134 + j*(163) -80 + j*(209) -155 + j*(46) -71 + j*(-19) -59 + j*(8) -74 + j*(-35) -5 + j*(-65) --40 + j*(6) -34 + j*(63) -116 + j*(-18) -32 + j*(-153) --170 + j*(-86) --151 + j*(177) -139 + j*(230) -243 + j*(-25) -66 + j*(-116) -74 + j*(6) -221 + j*(-123) -40 + j*(-356) --243 + j*(-229) --197 + j*(-8) --124 + j*(-42) --238 + j*(3) --178 + j*(206) -31 + j*(197) -49 + j*(81) -47 + j*(99) -131 + j*(35) -40 + j*(-76) --39 + j*(45) -158 + j*(82) -191 + j*(-202) --130 + j*(-276) --243 + j*(3) --60 + j*(94) --45 + j*(-2) --97 + j*(67) -23 + j*(94) -18 + j*(-47) --141 + j*(-11) --109 + j*(154) -14 + j*(155) -25 + j*(129) -100 + j*(160) -185 + j*(37) -62 + j*(-59) -3 + j*(79) -188 + j*(106) -227 + j*(-115) -23 + j*(-181) --41 + j*(-38) -45 + j*(1) -62 + j*(-45) -61 + j*(-53) -73 + j*(-99) -13 + j*(-140) --21 + j*(-116) --33 + j*(-151) --171 + j*(-154) --229 + j*(52) --4 + j*(153) -103 + j*(-88) --177 + j*(-197) --326 + j*(118) --32 + j*(326) -197 + j*(108) -51 + j*(-71) --46 + j*(61) -132 + j*(113) -211 + j*(-117) --11 + j*(-269) --214 + j*(-139) --204 + j*(35) --146 + j*(99) --97 + j*(165) -25 + j*(192) -98 + j*(83) -19 + j*(37) -25 + j*(147) -209 + j*(139) -269 + j*(-86) -95 + j*(-238) --99 + j*(-180) --173 + j*(-10) --62 + j*(173) -209 + j*(134) -254 + j*(-197) --91 + j*(-333) --283 + j*(-34) --62 + j*(144) -40 + j*(-25) --119 + j*(-35) --71 + j*(138) -100 + j*(65) -6 + j*(-73) --84 + j*(53) -74 + j*(112) -125 + j*(-59) --14 + j*(-108) --41 + j*(-36) --42 + j*(-70) --158 + j*(-33) --133 + j*(139) -28 + j*(144) -23 + j*(42) --23 + j*(112) -120 + j*(163) -221 + j*(-5) -98 + j*(-145) --37 + j*(-106) --77 + j*(-18) --59 + j*(86) -88 + j*(149) -236 + j*(-10) -112 + j*(-234) --153 + j*(-170) --163 + j*(105) -103 + j*(191) -279 + j*(-30) -151 + j*(-290) --133 + j*(-298) --257 + j*(-75) --139 + j*(90) --11 + j*(49) --37 + j*(-28) --92 + j*(16) --48 + j*(84) -35 + j*(72) -73 + j*(-1) -42 + j*(-86) --60 + j*(-117) --154 + j*(-37) --120 + j*(92) -1 + j*(97) -3 + j*(-5) --102 + j*(25) --38 + j*(170) -160 + j*(95) -95 + j*(-149) --180 + j*(-106) --170 + j*(175) -74 + j*(199) -105 + j*(33) -28 + j*(47) -117 + j*(69) -129 + j*(-82) --30 + j*(-98) --29 + j*(21) -37 + j*(-44) --129 + j*(-81) --194 + j*(180) -102 + j*(317) -298 + j*(81) -173 + j*(-95) -102 + j*(-45) -161 + j*(-87) -81 + j*(-207) --82 + j*(-163) --88 + j*(-7) -56 + j*(30) -127 + j*(-134) --72 + j*(-274) --305 + j*(-72) --132 + j*(230) -192 + j*(95) -82 + j*(-211) --176 + j*(-114) --77 + j*(59) --11 + j*(-83) --235 + j*(-65) --198 + j*(243) -132 + j*(240) -163 + j*(-30) -12 + j*(-59) -31 + j*(-41) --71 + j*(-137) --261 + j*(53) --30 + j*(332) -298 + j*(107) -107 + j*(-206) --142 + j*(-31) -54 + j*(141) -179 + j*(-92) --74 + j*(-200) --170 + j*(34) -23 + j*(98) -40 + j*(-74) --140 + j*(-59) --141 + j*(135) -32 + j*(186) -118 + j*(77) -79 + j*(4) -48 + j*(21) -94 + j*(35) -141 + j*(-46) -68 + j*(-148) --57 + j*(-112) --39 + j*(-5) -47 + j*(-55) --49 + j*(-160) --205 + j*(-52) --132 + j*(129) -9 + j*(98) --30 + j*(44) --6 + j*(156) -211 + j*(107) -202 + j*(-187) --104 + j*(-248) --214 + j*(-8) --91 + j*(83) --95 + j*(62) --86 + j*(191) -116 + j*(219) -183 + j*(42) -83 + j*(14) -173 + j*(68) -264 + j*(-135) -28 + j*(-305) --180 + j*(-119) --67 + j*(59) -47 + j*(-4) -14 + j*(-62) --4 + j*(-70) --54 + j*(-95) --126 + j*(-25) --64 + j*(67) -6 + j*(30) --21 + j*(11) -15 + j*(41) -45 + j*(-38) --64 + j*(-52) --44 + j*(86) -132 + j*(28) -57 + j*(-187) --176 + j*(-132) --165 + j*(63) --75 + j*(78) --80 + j*(124) -78 + j*(195) -228 + j*(-22) --4 + j*(-223) --209 + j*(0) -10 + j*(181) -164 + j*(-49) --78 + j*(-202) --262 + j*(8) --151 + j*(211) -1 + j*(238) -120 + j*(220) -247 + j*(115) -237 + j*(-69) -106 + j*(-139) -52 + j*(-100) -54 + j*(-134) --59 + j*(-187) --202 + j*(-62) --113 + j*(153) -134 + j*(106) -117 + j*(-168) --192 + j*(-185) --261 + j*(141) -46 + j*(265) -199 + j*(12) -1 + j*(-146) --157 + j*(-1) --92 + j*(164) -56 + j*(206) -194 + j*(130) -205 + j*(-42) -58 + j*(-83) -63 + j*(59) -267 + j*(-2) -223 + j*(-295) --92 + j*(-331) --177 + j*(-91) --37 + j*(-39) --65 + j*(-134) --171 + j*(-64) --117 + j*(47) --39 + j*(30) --30 + j*(-4) --33 + j*(-50) --153 + j*(-89) --280 + j*(112) --45 + j*(370) -330 + j*(176) -233 + j*(-250) --165 + j*(-257) --235 + j*(44) --67 + j*(118) --48 + j*(67) --37 + j*(130) -82 + j*(110) -69 + j*(-7) --2 + j*(18) -66 + j*(23) -4 + j*(-115) --230 + j*(-1) --110 + j*(342) -310 + j*(286) -354 + j*(-125) -48 + j*(-234) --42 + j*(-73) -11 + j*(-70) --78 + j*(-76) --73 + j*(71) -103 + j*(57) -84 + j*(-134) --106 + j*(-129) --124 + j*(27) --36 + j*(40) --80 + j*(10) --114 + j*(134) -54 + j*(240) -247 + j*(107) -209 + j*(-124) -13 + j*(-175) --80 + j*(-55) --42 + j*(37) -24 + j*(83) -164 + j*(77) -269 + j*(-146) -24 + j*(-402) --358 + j*(-215) --275 + j*(216) -124 + j*(223) -179 + j*(-100) --56 + j*(-172) --129 + j*(-26) --68 + j*(35) --28 + j*(37) -10 + j*(16) --11 + j*(-30) --37 + j*(6) -37 + j*(-8) --33 + j*(-153) --266 + j*(-46) --162 + j*(266) -182 + j*(187) -122 + j*(-136) --151 + j*(-84) --108 + j*(118) --5 + j*(82) --60 + j*(91) -23 + j*(199) -167 + j*(116) -136 + j*(15) -152 + j*(13) -181 + j*(-128) --24 + j*(-211) --124 + j*(-5) -68 + j*(65) -100 + j*(-121) --51 + j*(-142) --59 + j*(-98) --165 + j*(-158) --366 + j*(54) --148 + j*(388) -223 + j*(250) -158 + j*(-40) -1 + j*(21) -99 + j*(75) -97 + j*(-37) -21 + j*(12) -141 + j*(35) -142 + j*(-153) --66 + j*(-161) --83 + j*(11) -17 + j*(23) -25 + j*(18) -141 + j*(21) -177 + j*(-226) --158 + j*(-329) --309 + j*(18) -6 + j*(153) -71 + j*(-148) --248 + j*(-166) --279 + j*(146) --52 + j*(199) --49 + j*(99) --93 + j*(208) -93 + j*(319) -321 + j*(184) -340 + j*(-88) -131 + j*(-234) --27 + j*(-103) -121 + j*(-9) -181 + j*(-267) --188 + j*(-376) --365 + j*(25) -10 + j*(214) -159 + j*(-136) --173 + j*(-258) --288 + j*(6) --164 + j*(73) --237 + j*(85) --181 + j*(339) -178 + j*(332) -226 + j*(-12) --47 + j*(-44) --12 + j*(185) -211 + j*(103) -128 + j*(-105) --33 + j*(-25) -66 + j*(81) -156 + j*(-54) -0 + j*(-157) --127 + j*(-10) --4 + j*(132) -139 + j*(40) -79 + j*(-74) -23 + j*(-24) -107 + j*(-37) -53 + j*(-196) --178 + j*(-147) --179 + j*(122) -74 + j*(182) -185 + j*(-1) -119 + j*(-127) -28 + j*(-185) --113 + j*(-173) --170 + j*(-17) --35 + j*(49) --16 + j*(-71) --151 + j*(-37) --85 + j*(115) -68 + j*(21) --51 + j*(-130) --218 + j*(-13) --162 + j*(153) --63 + j*(190) -18 + j*(219) -161 + j*(182) -217 + j*(19) -130 + j*(-104) -2 + j*(-137) --141 + j*(-49) --119 + j*(186) -168 + j*(240) -290 + j*(-35) -86 + j*(-157) -57 + j*(-26) -190 + j*(-136) --6 + j*(-339) --279 + j*(-161) --187 + j*(89) --35 + j*(71) --34 + j*(38) -9 + j*(36) --21 + j*(-38) --119 + j*(59) -58 + j*(194) -231 + j*(-33) --16 + j*(-212) --141 + j*(44) -158 + j*(81) -125 + j*(-313) --374 + j*(-289) --446 + j*(250) -17 + j*(442) -265 + j*(146) -147 + j*(-57) -49 + j*(-35) -74 + j*(-35) -49 + j*(-120) --98 + j*(-146) --208 + j*(21) --69 + j*(197) -124 + j*(98) -37 + j*(-71) --103 + j*(37) -32 + j*(169) -162 + j*(35) -54 + j*(-69) --1 + j*(23) -96 + j*(36) -104 + j*(-56) -58 + j*(-69) -78 + j*(-97) -1 + j*(-203) --190 + j*(-150) --219 + j*(67) --55 + j*(164) -41 + j*(95) -35 + j*(70) -101 + j*(92) -202 + j*(-23) -112 + j*(-209) --103 + j*(-188) --135 + j*(-6) --16 + j*(25) --25 + j*(-49) --83 + j*(2) --8 + j*(53) -23 + j*(-26) --57 + j*(-25) --11 + j*(57) -82 + j*(-37) --43 + j*(-152) --170 + j*(-37) --93 + j*(54) --96 + j*(-8) --214 + j*(91) --90 + j*(313) -190 + j*(255) -225 + j*(22) -115 + j*(-39) -119 + j*(-33) -105 + j*(-135) --41 + j*(-175) --135 + j*(-68) --116 + j*(19) --103 + j*(53) --94 + j*(129) -4 + j*(206) -153 + j*(180) -245 + j*(44) -206 + j*(-132) -28 + j*(-211) --133 + j*(-80) --57 + j*(109) -135 + j*(76) -141 + j*(-91) -40 + j*(-116) -51 + j*(-105) -4 + j*(-216) --210 + j*(-176) --216 + j*(76) -6 + j*(90) --40 + j*(-96) --239 + j*(27) --95 + j*(268) -145 + j*(173) -111 + j*(28) -119 + j*(60) -221 + j*(-74) -40 + j*(-259) --171 + j*(-100) --47 + j*(68) -50 + j*(-38) --37 + j*(-72) --7 + j*(-37) --42 + j*(-154) --260 + j*(-73) --182 + j*(211) -93 + j*(139) -1 + j*(-67) --121 + j*(69) -54 + j*(108) --10 + j*(-86) --221 + j*(101) -77 + j*(344) -349 + j*(-26) --51 + j*(-301) --306 + j*(91) -35 + j*(310) -177 + j*(62) -26 + j*(54) -174 + j*(157) -295 + j*(-98) -20 + j*(-240) --98 + j*(-3) -103 + j*(49) -100 + j*(-137) --69 + j*(-115) --49 + j*(13) -22 + j*(-11) --23 + j*(-35) --29 + j*(40) -65 + j*(64) -139 + j*(-15) -112 + j*(-129) -4 + j*(-163) --49 + j*(-100) --20 + j*(-83) --41 + j*(-118) --83 + j*(-96) --82 + j*(-107) --192 + j*(-139) --315 + j*(43) --140 + j*(250) -73 + j*(127) --40 + j*(-17) --107 + j*(146) -124 + j*(192) -196 + j*(-69) --19 + j*(-176) --128 + j*(-65) --133 + j*(-17) --197 + j*(58) --139 + j*(213) -13 + j*(219) -35 + j*(163) -75 + j*(223) -249 + j*(183) -296 + j*(-32) -154 + j*(-146) -62 + j*(-116) -40 + j*(-108) --14 + j*(-113) --75 + j*(-64) --81 + j*(28) -11 + j*(87) -102 + j*(11) -26 + j*(-83) --47 + j*(13) -97 + j*(66) -144 + j*(-139) --105 + j*(-196) --170 + j*(65) -74 + j*(124) -102 + j*(-91) --80 + j*(-80) --29 + j*(71) -97 + j*(2) -42 + j*(-81) -35 + j*(-62) -48 + j*(-177) --178 + j*(-238) --325 + j*(26) --100 + j*(229) -79 + j*(75) --45 + j*(-35) --101 + j*(106) -62 + j*(166) -164 + j*(25) -97 + j*(-110) --28 + j*(-144) --144 + j*(-75) --161 + j*(84) --7 + j*(173) -120 + j*(52) -18 + j*(-78) --114 + j*(42) -45 + j*(204) -273 + j*(22) -107 + j*(-272) --217 + j*(-142) --112 + j*(176) -195 + j*(71) -88 + j*(-234) --211 + j*(-156) --177 + j*(99) --6 + j*(92) --29 + j*(5) --69 + j*(59) --11 + j*(93) -20 + j*(63) -31 + j*(49) -30 + j*(6) --49 + j*(11) --37 + j*(144) -149 + j*(153) -198 + j*(-51) -23 + j*(-128) --43 + j*(4) -64 + j*(35) -70 + j*(-76) --52 + j*(-81) --86 + j*(45) -15 + j*(118) -117 + j*(75) -143 + j*(-13) -119 + j*(-71) -87 + j*(-121) -4 + j*(-158) --98 + j*(-84) --44 + j*(57) -132 + j*(25) -141 + j*(-175) --33 + j*(-253) --145 + j*(-178) --187 + j*(-118) --250 + j*(-28) --211 + j*(132) --40 + j*(179) -53 + j*(59) --20 + j*(-36) --122 + j*(10) --110 + j*(148) -61 + j*(212) -224 + j*(52) -129 + j*(-190) --135 + j*(-187) --214 + j*(35) --81 + j*(148) -1 + j*(98) --6 + j*(98) -69 + j*(136) -181 + j*(28) -91 + j*(-155) --130 + j*(-107) --113 + j*(127) -132 + j*(112) -103 + j*(-163) --225 + j*(-134) --235 + j*(238) -124 + j*(314) -231 + j*(42) -78 + j*(-9) -156 + j*(80) -275 + j*(-119) -40 + j*(-315) --192 + j*(-129) --70 + j*(52) -16 + j*(-64) --165 + j*(-95) --232 + j*(161) -25 + j*(338) -308 + j*(185) -317 + j*(-112) -103 + j*(-245) --50 + j*(-148) --11 + j*(-56) -17 + j*(-116) --97 + j*(-125) --129 + j*(23) -25 + j*(85) -115 + j*(-62) --6 + j*(-184) --159 + j*(-110) --139 + j*(45) --1 + j*(64) -28 + j*(-65) --100 + j*(-98) --138 + j*(18) --51 + j*(27) --122 + j*(-42) --230 + j*(123) --16 + j*(313) -245 + j*(122) -118 + j*(-151) --115 + j*(-88) --102 + j*(78) --15 + j*(105) -45 + j*(103) -127 + j*(21) -37 + j*(-133) --170 + j*(-50) --119 + j*(180) -85 + j*(175) -108 + j*(61) -115 + j*(46) -151 + j*(-66) --31 + j*(-154) --152 + j*(68) -88 + j*(200) -204 + j*(-35) --8 + j*(-97) -10 + j*(114) -246 + j*(33) -162 + j*(-222) --52 + j*(-168) --8 + j*(-47) -22 + j*(-113) --56 + j*(-87) -23 + j*(-35) -49 + j*(-194) --185 + j*(-232) --262 + j*(21) --47 + j*(101) -8 + j*(-89) --191 + j*(-145) --322 + j*(28) --266 + j*(245) --43 + j*(359) -177 + j*(213) -93 + j*(-14) --114 + j*(91) -46 + j*(342) -381 + j*(202) -356 + j*(-164) -76 + j*(-260) --67 + j*(-126) --42 + j*(-6) -54 + j*(9) -84 + j*(-112) --93 + j*(-175) --216 + j*(41) --4 + j*(220) -187 + j*(48) -62 + j*(-99) --8 + j*(18) -151 + j*(32) -170 + j*(-167) -1 + j*(-237) --81 + j*(-171) --116 + j*(-170) --235 + j*(-134) --296 + j*(37) --192 + j*(194) --21 + j*(214) -74 + j*(98) --1 + j*(-1) --93 + j*(92) -38 + j*(225) -244 + j*(106) -206 + j*(-135) -13 + j*(-202) --122 + j*(-124) --175 + j*(12) --77 + j*(171) -138 + j*(122) -132 + j*(-113) --93 + j*(-131) --113 + j*(52) -14 + j*(35) --81 + j*(-54) --184 + j*(119) -7 + j*(270) -177 + j*(148) -148 + j*(47) -192 + j*(47) -250 + j*(-116) -63 + j*(-264) --123 + j*(-127) --39 + j*(22) -52 + j*(-51) --25 + j*(-103) --47 + j*(-40) --6 + j*(-68) --97 + j*(-120) --204 + j*(-2) --122 + j*(153) -33 + j*(144) -76 + j*(43) -42 + j*(-7) -21 + j*(-5) -32 + j*(-12) -24 + j*(-70) --91 + j*(-107) --226 + j*(40) --106 + j*(296) -238 + j*(284) -373 + j*(-71) -105 + j*(-325) --190 + j*(-192) --182 + j*(65) --12 + j*(129) -65 + j*(48) -39 + j*(-4) -18 + j*(13) -54 + j*(33) -107 + j*(-6) -110 + j*(-91) -38 + j*(-165) --86 + j*(-168) --182 + j*(-47) --103 + j*(130) -128 + j*(115) -190 + j*(-144) --47 + j*(-298) --258 + j*(-156) --246 + j*(28) --178 + j*(105) --101 + j*(175) -53 + j*(149) -76 + j*(-33) --113 + j*(-80) --179 + j*(104) --24 + j*(184) -38 + j*(68) --64 + j*(44) --83 + j*(166) -38 + j*(235) -155 + j*(177) -173 + j*(84) -158 + j*(74) -257 + j*(64) -337 + j*(-165) -70 + j*(-406) --300 + j*(-202) --197 + j*(201) -158 + j*(170) -151 + j*(-98) --24 + j*(-82) -13 + j*(11) -29 + j*(-41) --23 + j*(28) -142 + j*(89) -243 + j*(-152) --11 + j*(-301) --160 + j*(-95) --9 + j*(-13) --18 + j*(-156) --180 + j*(-100) --137 + j*(49) --59 + j*(32) --93 + j*(57) -9 + j*(139) -139 + j*(30) -85 + j*(-95) -49 + j*(-113) --1 + j*(-236) --292 + j*(-232) --390 + j*(163) -18 + j*(347) -232 + j*(-16) --69 + j*(-199) --178 + j*(31) --9 + j*(29) --153 + j*(-123) --350 + j*(132) --78 + j*(395) -177 + j*(175) --3 + j*(17) --54 + j*(233) -233 + j*(250) -274 + j*(-47) -47 + j*(-99) -62 + j*(39) -161 + j*(-92) --80 + j*(-226) --301 + j*(77) --18 + j*(404) -385 + j*(230) -369 + j*(-156) -106 + j*(-264) --22 + j*(-159) --18 + j*(-98) --25 + j*(-91) --62 + j*(-67) --71 + j*(3) -14 + j*(64) -128 + j*(-19) -71 + j*(-185) --119 + j*(-175) --159 + j*(-13) --60 + j*(39) --55 + j*(-1) --75 + j*(60) -33 + j*(105) -115 + j*(1) -66 + j*(-100) -3 + j*(-122) --59 + j*(-150) --186 + j*(-126) --264 + j*(36) --168 + j*(209) -22 + j*(231) -126 + j*(107) -83 + j*(4) -36 + j*(27) -107 + j*(28) -112 + j*(-110) --60 + j*(-147) --120 + j*(21) -26 + j*(76) -58 + j*(-45) --23 + j*(-40) -44 + j*(-8) -48 + j*(-170) --195 + j*(-199) --287 + j*(54) --105 + j*(174) --40 + j*(91) --74 + j*(122) -21 + j*(158) -40 + j*(59) --60 + j*(115) -76 + j*(275) -334 + j*(137) -289 + j*(-160) -68 + j*(-228) --31 + j*(-156) --88 + j*(-124) --161 + j*(-33) --124 + j*(107) -8 + j*(153) -107 + j*(76) -85 + j*(-28) --11 + j*(-13) -36 + j*(100) -209 + j*(28) -150 + j*(-202) --91 + j*(-184) --93 + j*(16) -47 + j*(-1) --6 + j*(-98) --74 + j*(-21) -4 + j*(15) -9 + j*(-45) --18 + j*(-18) -45 + j*(-42) --28 + j*(-154) --188 + j*(-57) --95 + j*(119) -54 + j*(37) --26 + j*(-59) --64 + j*(36) -48 + j*(21) -4 + j*(-108) --123 + j*(-68) --115 + j*(13) --122 + j*(18) --150 + j*(101) --64 + j*(182) -11 + j*(168) -74 + j*(197) -255 + j*(128) -258 + j*(-156) --20 + j*(-245) --132 + j*(-64) --83 + j*(-25) --188 + j*(30) --97 + j*(302) -292 + j*(246) -298 + j*(-159) --21 + j*(-179) -32 + j*(19) -153 + j*(-161) --119 + j*(-269) --227 + j*(11) -1 + j*(71) --40 + j*(-97) --175 + j*(52) -53 + j*(170) -153 + j*(-105) --145 + j*(-195) --250 + j*(85) --49 + j*(207) -48 + j*(129) -20 + j*(-16) --153 + j*(39) --67 + j*(248) -168 + j*(204) -190 + j*(6) -79 + j*(-42) -55 + j*(11) -116 + j*(11) -151 + j*(-91) -37 + j*(-217) --189 + j*(-141) --180 + j*(150) -139 + j*(216) -272 + j*(-98) -0 + j*(-273) --162 + j*(-72) --13 + j*(18) --18 + j*(-144) --253 + j*(-80) --201 + j*(224) -119 + j*(223) -158 + j*(-62) --76 + j*(-111) --123 + j*(72) --8 + j*(115) -5 + j*(85) -42 + j*(146) -187 + j*(103) -190 + j*(-75) -51 + j*(-117) -18 + j*(-45) -43 + j*(-53) -4 + j*(-48) -48 + j*(8) -132 + j*(-81) -28 + j*(-197) --75 + j*(-110) -22 + j*(-79) --21 + j*(-257) --312 + j*(-221) --363 + j*(127) --65 + j*(267) -102 + j*(74) -8 + j*(-53) --57 + j*(-21) --49 + j*(-23) --98 + j*(-45) --168 + j*(1) --192 + j*(103) --134 + j*(218) -10 + j*(260) -124 + j*(185) -151 + j*(85) -132 + j*(1) -42 + j*(-52) --50 + j*(34) -49 + j*(156) -209 + j*(53) -132 + j*(-117) -2 + j*(-72) -53 + j*(-21) -35 + j*(-124) --127 + j*(-79) --94 + j*(112) -71 + j*(101) -65 + j*(6) -58 + j*(45) -162 + j*(-21) -55 + j*(-196) --175 + j*(-70) --47 + j*(199) -252 + j*(92) -190 + j*(-209) --69 + j*(-199) --71 + j*(-8) -73 + j*(-34) -11 + j*(-181) --168 + j*(-110) --112 + j*(105) -133 + j*(71) -139 + j*(-204) --138 + j*(-275) --276 + j*(-60) --179 + j*(93) --94 + j*(119) -18 + j*(148) -162 + j*(6) -26 + j*(-228) --247 + j*(-132) --196 + j*(110) --56 + j*(52) --201 + j*(25) --186 + j*(303) -185 + j*(322) -255 + j*(-55) --76 + j*(-139) --141 + j*(135) -88 + j*(190) -140 + j*(19) -35 + j*(-28) --6 + j*(30) -34 + j*(95) -163 + j*(86) -219 + j*(-117) --15 + j*(-264) --230 + j*(-56) --86 + j*(169) -83 + j*(84) -21 + j*(7) -28 + j*(96) -162 + j*(54) -146 + j*(-94) -45 + j*(-119) -13 + j*(-106) --49 + j*(-112) --103 + j*(-21) --24 + j*(58) -58 + j*(6) -44 + j*(-64) --5 + j*(-103) --108 + j*(-93) --155 + j*(63) -35 + j*(171) -190 + j*(-23) -7 + j*(-206) --175 + j*(-45) --35 + j*(121) -113 + j*(-3) -18 + j*(-146) --119 + j*(-103) --148 + j*(11) --88 + j*(97) -18 + j*(88) -26 + j*(-2) --47 + j*(23) -50 + j*(112) -197 + j*(-47) -23 + j*(-272) --256 + j*(-141) --197 + j*(119) --28 + j*(103) --75 + j*(49) --61 + j*(182) -146 + j*(168) -159 + j*(-66) --41 + j*(-97) --52 + j*(81) -131 + j*(78) -152 + j*(-101) --6 + j*(-171) --116 + j*(-80) --110 + j*(36) --23 + j*(101) -86 + j*(69) -116 + j*(-40) -59 + j*(-113) --4 + j*(-137) --81 + j*(-152) --188 + j*(-98) --225 + j*(40) --157 + j*(156) --58 + j*(203) -49 + j*(203) -142 + j*(134) -159 + j*(27) -109 + j*(-42) -33 + j*(-64) --49 + j*(4) -13 + j*(147) -227 + j*(116) -262 + j*(-137) -35 + j*(-221) --35 + j*(-57) -105 + j*(-54) -57 + j*(-218) --124 + j*(-179) --112 + j*(-45) --62 + j*(-72) --150 + j*(-71) --165 + j*(53) --93 + j*(107) --51 + j*(159) -119 + j*(214) -309 + j*(1) -148 + j*(-280) --118 + j*(-215) --103 + j*(-68) --106 + j*(-115) --245 + j*(-18) --124 + j*(192) -93 + j*(70) --49 + j*(-119) --227 + j*(47) --80 + j*(221) -50 + j*(139) -16 + j*(105) -64 + j*(148) -132 + j*(102) -154 + j*(76) -253 + j*(1) -211 + j*(-228) --62 + j*(-268) --141 + j*(-52) --21 + j*(-23) --99 + j*(-81) --146 + j*(102) -98 + j*(163) -176 + j*(-89) --30 + j*(-168) --74 + j*(-58) --72 + j*(-105) --255 + j*(-44) --206 + j*(249) -106 + j*(258) -140 + j*(19) -6 + j*(35) -111 + j*(107) -173 + j*(-62) -7 + j*(-121) --20 + j*(1) -59 + j*(-44) --64 + j*(-100) --124 + j*(90) -105 + j*(177) -235 + j*(-37) -90 + j*(-192) --28 + j*(-144) --42 + j*(-128) --148 + j*(-137) --256 + j*(38) --103 + j*(261) -194 + j*(200) -233 + j*(-95) --8 + j*(-198) --115 + j*(-16) -40 + j*(62) -106 + j*(-97) --47 + j*(-189) --173 + j*(-98) --190 + j*(20) --149 + j*(123) --37 + j*(182) -63 + j*(129) -74 + j*(73) -105 + j*(53) -122 + j*(-39) -19 + j*(-87) --16 + j*(11) -98 + j*(8) -78 + j*(-145) --92 + j*(-151) --136 + j*(-19) --94 + j*(37) --70 + j*(81) -18 + j*(103) -47 + j*(9) --56 + j*(27) -33 + j*(182) -274 + j*(57) -168 + j*(-253) --151 + j*(-201) --143 + j*(74) -79 + j*(80) -96 + j*(-104) --49 + j*(-161) --158 + j*(-77) --153 + j*(47) --65 + j*(85) --58 + j*(42) --104 + j*(119) -37 + j*(215) -175 + j*(63) -37 + j*(-49) -5 + j*(101) -208 + j*(50) -102 + j*(-205) --168 + j*(-50) -47 + j*(210) -306 + j*(-73) --16 + j*(-332) --255 + j*(-18) -41 + j*(160) -139 + j*(-130) --158 + j*(-171) --180 + j*(115) -55 + j*(134) -56 + j*(-25) --40 + j*(18) -54 + j*(101) -173 + j*(-6) -116 + j*(-182) --86 + j*(-226) --232 + j*(-57) --132 + j*(143) -54 + j*(100) -23 + j*(-40) --83 + j*(20) -1 + j*(123) -117 + j*(54) -103 + j*(-50) -57 + j*(-96) --11 + j*(-141) --128 + j*(-109) --163 + j*(13) --107 + j*(88) --53 + j*(115) -16 + j*(123) -62 + j*(72) -40 + j*(47) -73 + j*(71) -129 + j*(-10) -32 + j*(-91) --40 + j*(18) -92 + j*(69) -134 + j*(-86) --20 + j*(-116) --22 + j*(19) -113 + j*(-21) -64 + j*(-169) --74 + j*(-158) --113 + j*(-92) --147 + j*(-40) --122 + j*(71) -29 + j*(62) -12 + j*(-122) --220 + j*(-116) --272 + j*(134) --90 + j*(245) --1 + j*(192) -25 + j*(218) -171 + j*(227) -279 + j*(64) -198 + j*(-95) -87 + j*(-100) -73 + j*(-67) -80 + j*(-100) -35 + j*(-149) --53 + j*(-163) --153 + j*(-111) --209 + j*(27) --129 + j*(186) -68 + j*(223) -205 + j*(86) -179 + j*(-74) -88 + j*(-138) -5 + j*(-157) --96 + j*(-119) --115 + j*(1) --16 + j*(38) --15 + j*(-49) --125 + j*(6) --32 + j*(174) -199 + j*(79) -140 + j*(-194) --129 + j*(-188) --168 + j*(26) --37 + j*(71) --35 + j*(20) --45 + j*(83) -76 + j*(84) -86 + j*(-76) --113 + j*(-103) --179 + j*(133) -62 + j*(269) -273 + j*(88) -204 + j*(-132) -66 + j*(-167) -2 + j*(-162) --103 + j*(-144) --148 + j*(13) -28 + j*(86) -103 + j*(-114) --116 + j*(-188) --182 + j*(15) --18 + j*(18) --134 + j*(-136) --347 + j*(89) --95 + j*(383) -220 + j*(180) -69 + j*(-60) --48 + j*(91) -146 + j*(103) -101 + j*(-139) --162 + j*(-80) --118 + j*(158) -24 + j*(144) --9 + j*(153) -144 + j*(295) -445 + j*(102) -343 + j*(-304) --41 + j*(-339) --161 + j*(-82) --35 + j*(47) -82 + j*(1) -88 + j*(-138) --106 + j*(-212) --285 + j*(14) --85 + j*(303) -262 + j*(192) -267 + j*(-119) -84 + j*(-187) -59 + j*(-170) --18 + j*(-281) --279 + j*(-235) --345 + j*(93) --56 + j*(264) -149 + j*(54) --6 + j*(-124) --141 + j*(19) -14 + j*(121) -86 + j*(-53) --107 + j*(-88) --104 + j*(133) -148 + j*(91) -79 + j*(-190) --215 + j*(-110) --141 + j*(163) -71 + j*(98) --9 + j*(-30) --50 + j*(76) -74 + j*(47) --21 + j*(-69) --111 + j*(97) -124 + j*(161) -175 + j*(-124) --117 + j*(-168) --140 + j*(79) -18 + j*(42) --129 + j*(-30) --170 + j*(247) -187 + j*(317) -292 + j*(-23) -37 + j*(-107) -30 + j*(71) -175 + j*(-1) -69 + j*(-127) --26 + j*(-14) -93 + j*(53) -172 + j*(-49) -153 + j*(-153) -76 + j*(-268) --137 + j*(-300) --285 + j*(-99) --179 + j*(86) --56 + j*(67) --50 + j*(33) --41 + j*(37) --47 + j*(40) --22 + j*(98) -101 + j*(63) -71 + j*(-103) --99 + j*(-73) --39 + j*(54) -16 + j*(-78) --238 + j*(-69) --216 + j*(317) -238 + j*(336) -301 + j*(-74) -30 + j*(-109) -119 + j*(-5) -102 + j*(-274) --336 + j*(-198) --234 + j*(338) -317 + j*(203) -107 + j*(-310) --373 + j*(9) -39 + j*(494) -548 + j*(83) -259 + j*(-392) --59 + j*(-276) --50 + j*(-222) --245 + j*(-243) --345 + j*(76) --46 + j*(217) -41 + j*(0) --101 + j*(28) -41 + j*(107) -47 + j*(-132) --296 + j*(-61) --186 + j*(387) -322 + j*(310) -317 + j*(-164) --23 + j*(-210) --63 + j*(-51) --68 + j*(-73) --175 + j*(40) --20 + j*(210) -158 + j*(66) -35 + j*(-66) --25 + j*(49) -91 + j*(58) -83 + j*(-30) -75 + j*(-8) -147 + j*(-103) --15 + j*(-257) --227 + j*(-94) --94 + j*(96) -3 + j*(-42) --209 + j*(-49) --199 + j*(257) -140 + j*(306) -250 + j*(40) -117 + j*(-65) -97 + j*(-48) -59 + j*(-125) --77 + j*(-87) --37 + j*(62) -100 + j*(11) -37 + j*(-114) --59 + j*(-43) -25 + j*(4) -25 + j*(-114) --153 + j*(-93) --145 + j*(137) -109 + j*(171) -191 + j*(-75) --13 + j*(-193) --144 + j*(-52) --71 + j*(59) --11 + j*(46) -20 + j*(59) -115 + j*(11) -86 + j*(-164) --141 + j*(-180) --206 + j*(53) --4 + j*(141) -72 + j*(-33) --84 + j*(-98) --161 + j*(37) --96 + j*(133) --21 + j*(173) -110 + j*(175) -214 + j*(13) -74 + j*(-158) --111 + j*(-55) --28 + j*(112) -115 + j*(41) -57 + j*(-75) --24 + j*(-36) --1 + j*(-3) --20 + j*(-16) --31 + j*(53) -78 + j*(77) -124 + j*(-49) -11 + j*(-101) --12 + j*(-10) -84 + j*(-37) -29 + j*(-175) --149 + j*(-140) --162 + j*(32) --39 + j*(63) --34 + j*(-16) --105 + j*(19) --59 + j*(109) -41 + j*(71) -3 + j*(-23) --98 + j*(30) --42 + j*(162) -121 + j*(127) -112 + j*(-46) --64 + j*(-49) --78 + j*(147) -136 + j*(196) -232 + j*(0) -93 + j*(-115) --5 + j*(-24) -59 + j*(53) -144 + j*(33) -218 + j*(-44) -221 + j*(-222) -6 + j*(-361) --238 + j*(-199) --153 + j*(69) -88 + j*(24) -55 + j*(-197) --150 + j*(-198) --190 + j*(-41) --102 + j*(-2) --101 + j*(-59) --194 + j*(-53) --261 + j*(78) --156 + j*(254) -87 + j*(235) -144 + j*(-18) --100 + j*(-113) --231 + j*(132) --11 + j*(312) -197 + j*(161) -122 + j*(-5) -43 + j*(53) -148 + j*(74) -173 + j*(-95) --18 + j*(-148) --86 + j*(41) -116 + j*(92) -151 + j*(-148) --134 + j*(-187) --187 + j*(127) -143 + j*(188) -202 + j*(-142) --109 + j*(-194) --141 + j*(74) -67 + j*(52) --37 + j*(-107) --177 + j*(85) -66 + j*(231) -214 + j*(-20) --19 + j*(-139) --97 + j*(74) -100 + j*(126) -143 + j*(-30) -59 + j*(-60) -67 + j*(-48) -49 + j*(-99) --6 + j*(-85) -2 + j*(-83) --78 + j*(-118) --170 + j*(35) -22 + j*(202) -261 + j*(16) -144 + j*(-269) --115 + j*(-267) --222 + j*(-120) --230 + j*(24) --117 + j*(153) -61 + j*(76) --21 + j*(-107) --218 + j*(6) --86 + j*(230) -141 + j*(103) -21 + j*(-98) --153 + j*(20) --58 + j*(168) -37 + j*(133) -56 + j*(142) -192 + j*(128) -230 + j*(-85) -17 + j*(-165) --42 + j*(20) -144 + j*(10) -78 + j*(-226) --221 + j*(-146) --165 + j*(190) -173 + j*(174) -194 + j*(-137) --57 + j*(-189) --112 + j*(-10) -4 + j*(12) --13 + j*(-78) --116 + j*(-51) --128 + j*(61) --35 + j*(141) -119 + j*(104) -158 + j*(-125) --125 + j*(-265) --395 + j*(30) --168 + j*(416) -249 + j*(329) -288 + j*(0) -127 + j*(-76) -122 + j*(-61) -76 + j*(-166) --107 + j*(-134) --115 + j*(67) -70 + j*(103) -136 + j*(-47) -35 + j*(-147) --89 + j*(-117) --135 + j*(0) --57 + j*(94) -35 + j*(58) -16 + j*(11) -26 + j*(54) -121 + j*(8) -77 + j*(-132) --66 + j*(-115) --62 + j*(-21) --44 + j*(-54) --147 + j*(-11) --90 + j*(163) -119 + j*(127) -98 + j*(-64) --51 + j*(-28) -23 + j*(93) -136 + j*(-2) -59 + j*(-98) -25 + j*(-46) -92 + j*(-109) --35 + j*(-244) --247 + j*(-124) --176 + j*(107) -21 + j*(59) --58 + j*(-110) --253 + j*(-2) --168 + j*(241) -71 + j*(222) -96 + j*(59) -28 + j*(57) -93 + j*(68) -86 + j*(-60) --78 + j*(-46) --54 + j*(137) -134 + j*(111) -105 + j*(-52) --15 + j*(-2) -73 + j*(86) -153 + j*(-13) -109 + j*(-70) -141 + j*(-113) -49 + j*(-303) --291 + j*(-239) --296 + j*(175) -111 + j*(217) -139 + j*(-158) --216 + j*(-148) --193 + j*(179) -64 + j*(148) --6 + j*(-11) --98 + j*(140) -112 + j*(226) -215 + j*(31) -93 + j*(-42) -110 + j*(34) -212 + j*(-61) -122 + j*(-230) --73 + j*(-220) --151 + j*(-72) --80 + j*(49) -42 + j*(33) -48 + j*(-71) --34 + j*(-74) --5 + j*(-15) -45 + j*(-105) --96 + j*(-188) --226 + j*(-47) --139 + j*(88) --63 + j*(54) --95 + j*(61) --36 + j*(117) -24 + j*(41) --85 + j*(0) --132 + j*(162) -52 + j*(274) -237 + j*(158) -254 + j*(-29) -160 + j*(-160) -0 + j*(-185) --93 + j*(-59) -9 + j*(45) -118 + j*(-73) --11 + j*(-226) --217 + j*(-146) --233 + j*(57) --114 + j*(142) --49 + j*(125) --33 + j*(145) -49 + j*(185) -175 + j*(114) -163 + j*(-51) -4 + j*(-78) --24 + j*(78) -165 + j*(107) -232 + j*(-113) -29 + j*(-233) --103 + j*(-90) --6 + j*(2) -33 + j*(-94) --83 + j*(-117) --119 + j*(-3) --40 + j*(37) --17 + j*(-3) --37 + j*(-3) --30 + j*(6) --42 + j*(1) --52 + j*(42) -6 + j*(63) -35 + j*(1) --27 + j*(-25) --57 + j*(37) --6 + j*(85) -65 + j*(64) -93 + j*(-26) --6 + j*(-112) --162 + j*(-6) --62 + j*(223) -232 + j*(156) -214 + j*(-170) --101 + j*(-198) --153 + j*(74) -57 + j*(127) -87 + j*(-12) -13 + j*(11) -103 + j*(54) -158 + j*(-85) -23 + j*(-167) --68 + j*(-73) --16 + j*(6) -66 + j*(-13) -106 + j*(-112) -16 + j*(-253) --206 + j*(-235) --287 + j*(-20) --161 + j*(94) --115 + j*(45) --179 + j*(110) --66 + j*(265) -177 + j*(206) -229 + j*(-56) -29 + j*(-212) --180 + j*(-122) --211 + j*(67) --111 + j*(175) --7 + j*(196) -98 + j*(174) -173 + j*(52) -76 + j*(-78) --70 + j*(-5) --7 + j*(144) -130 + j*(100) -120 + j*(18) -137 + j*(25) -191 + j*(-89) -27 + j*(-209) --123 + j*(-37) -49 + j*(95) -144 + j*(-89) --53 + j*(-139) --40 + j*(62) -180 + j*(-23) -50 + j*(-293) --267 + j*(-175) --211 + j*(141) -48 + j*(148) -93 + j*(-32) --21 + j*(-88) --88 + j*(-21) --52 + j*(52) -20 + j*(28) --15 + j*(-39) --94 + j*(19) --23 + j*(121) -88 + j*(68) -71 + j*(-22) -28 + j*(-31) -0 + j*(-36) --36 + j*(21) -67 + j*(81) -156 + j*(-72) --31 + j*(-177) --110 + j*(28) -133 + j*(40) -74 + j*(-280) --330 + j*(-195) --272 + j*(250) -146 + j*(238) -168 + j*(-88) --37 + j*(-124) --72 + j*(-48) --106 + j*(-19) --66 + j*(86) -80 + j*(-11) --115 + j*(-216) --410 + j*(63) --127 + j*(443) -249 + j*(223) -89 + j*(-33) -8 + j*(133) -240 + j*(65) -91 + j*(-233) --233 + j*(-70) --98 + j*(220) -87 + j*(124) -2 + j*(88) -93 + j*(220) -280 + j*(86) -178 + j*(-92) -82 + j*(-25) -150 + j*(-11) -131 + j*(-62) -169 + j*(-24) -284 + j*(-177) -86 + j*(-409) --194 + j*(-261) --110 + j*(-54) --40 + j*(-146) --190 + j*(-113) --112 + j*(75) -57 + j*(-34) --89 + j*(-157) --156 + j*(21) -44 + j*(25) --8 + j*(-208) --265 + j*(-150) --250 + j*(71) --143 + j*(82) --176 + j*(101) --104 + j*(218) -48 + j*(175) -52 + j*(69) -42 + j*(62) -76 + j*(-13) --42 + j*(-117) --218 + j*(-21) --216 + j*(183) --65 + j*(296) -95 + j*(268) -155 + j*(155) -118 + j*(115) -166 + j*(144) -257 + j*(42) -170 + j*(-81) -105 + j*(-21) -202 + j*(-64) -71 + j*(-257) --216 + j*(-83) --33 + j*(272) -344 + j*(103) -203 + j*(-236) --35 + j*(-91) -180 + j*(45) -285 + j*(-255) --16 + j*(-395) --144 + j*(-194) --54 + j*(-185) --204 + j*(-263) --358 + j*(-25) --134 + j*(192) -87 + j*(17) --61 + j*(-190) --274 + j*(-67) --202 + j*(146) --24 + j*(114) --71 + j*(-14) --197 + j*(93) --50 + j*(267) -165 + j*(129) -54 + j*(-76) --102 + j*(35) -39 + j*(137) -101 + j*(-47) --115 + j*(-85) --144 + j*(139) -53 + j*(161) -45 + j*(17) --57 + j*(78) -47 + j*(170) -136 + j*(62) -45 + j*(-3) -9 + j*(91) -122 + j*(133) -210 + j*(30) -152 + j*(-102) -6 + j*(-80) -28 + j*(83) -249 + j*(54) -253 + j*(-223) --12 + j*(-285) --82 + j*(-117) --32 + j*(-133) --198 + j*(-104) --148 + j*(222) -318 + j*(199) -364 + j*(-360) --198 + j*(-505) --407 + j*(-36) --81 + j*(146) -15 + j*(-82) --185 + j*(-115) --231 + j*(62) --135 + j*(154) --32 + j*(180) -85 + j*(121) -83 + j*(-10) --6 + j*(-30) --6 + j*(5) --22 + j*(-37) --99 + j*(20) --8 + j*(119) -107 + j*(-13) --62 + j*(-148) --233 + j*(29) --110 + j*(229) -69 + j*(205) -139 + j*(107) -148 + j*(-12) -15 + j*(-99) --117 + j*(44) -35 + j*(213) -230 + j*(81) -153 + j*(-101) -45 + j*(-81) -46 + j*(-70) --18 + j*(-79) --33 + j*(27) -107 + j*(33) -115 + j*(-139) --54 + j*(-181) --138 + j*(-85) --167 + j*(-8) --170 + j*(141) -24 + j*(254) -207 + j*(93) -97 + j*(-66) -15 + j*(45) -188 + j*(88) -281 + j*(-124) -144 + j*(-306) --56 + j*(-351) --270 + j*(-260) --339 + j*(7) --134 + j*(148) --58 + j*(4) --243 + j*(64) --98 + j*(387) -372 + j*(268) -358 + j*(-269) --140 + j*(-374) --326 + j*(1) --108 + j*(205) -54 + j*(144) -113 + j*(67) -145 + j*(-55) -17 + j*(-186) --179 + j*(-106) --173 + j*(105) -6 + j*(173) -120 + j*(52) -62 + j*(-79) --54 + j*(-76) --91 + j*(-2) --81 + j*(37) --84 + j*(86) --18 + j*(156) -94 + j*(109) -66 + j*(1) --30 + j*(43) -35 + j*(156) -177 + j*(122) -224 + j*(-8) -184 + j*(-121) -73 + j*(-189) --50 + j*(-130) --21 + j*(-18) -64 + j*(-62) -3 + j*(-136) --38 + j*(-88) -1 + j*(-141) --177 + j*(-245) --417 + j*(-3) --223 + j*(356) -144 + j*(274) -133 + j*(2) --23 + j*(29) -54 + j*(130) -156 + j*(40) -117 + j*(-54) -80 + j*(-83) -22 + j*(-125) --69 + j*(-81) --42 + j*(8) -26 + j*(-35) --51 + j*(-103) --154 + j*(-21) --129 + j*(120) --1 + j*(198) -175 + j*(153) -254 + j*(-54) -97 + j*(-231) --97 + j*(-167) --103 + j*(-42) --78 + j*(-31) --126 + j*(18) --64 + j*(139) -108 + j*(125) -172 + j*(-43) -69 + j*(-180) --100 + j*(-182) --194 + j*(-36) --94 + j*(103) -51 + j*(16) --61 + j*(-156) --307 + j*(-35) --250 + j*(295) -100 + j*(351) -247 + j*(54) -11 + j*(-116) --156 + j*(104) -71 + j*(301) -324 + j*(105) -209 + j*(-163) -2 + j*(-124) -25 + j*(-20) -53 + j*(-74) --29 + j*(-71) --11 + j*(-1) -18 + j*(-50) --83 + j*(-41) --61 + j*(117) -119 + j*(110) -141 + j*(-40) -78 + j*(-63) -103 + j*(-100) --4 + j*(-199) --146 + j*(-67) -11 + j*(60) -96 + j*(-160) --206 + j*(-229) --296 + j*(124) -49 + j*(225) -127 + j*(-81) --148 + j*(-121) --178 + j*(133) -12 + j*(196) -109 + j*(129) -199 + j*(47) -197 + j*(-168) --59 + j*(-260) --194 + j*(-43) --33 + j*(56) --24 + j*(-89) --209 + j*(-33) --154 + j*(204) -91 + j*(205) -155 + j*(6) -28 + j*(-95) --91 + j*(-32) --73 + j*(102) -71 + j*(110) -86 + j*(-47) --96 + j*(-49) --97 + j*(175) -162 + j*(208) -236 + j*(-28) -86 + j*(-104) -83 + j*(-31) -144 + j*(-143) --41 + j*(-261) --227 + j*(-84) --100 + j*(122) -78 + j*(37) -5 + j*(-104) --107 + j*(-34) --36 + j*(46) --1 + j*(-52) --163 + j*(-68) --221 + j*(161) -13 + j*(306) -222 + j*(154) -190 + j*(-35) -95 + j*(-87) -23 + j*(-92) --39 + j*(-25) -51 + j*(57) -160 + j*(-88) --40 + j*(-257) --277 + j*(-37) --72 + j*(240) -201 + j*(61) -33 + j*(-181) --167 + j*(-4) -23 + j*(164) -177 + j*(-35) --9 + j*(-182) --146 + j*(-37) --55 + j*(64) --23 + j*(12) --80 + j*(59) -23 + j*(174) -213 + j*(78) -189 + j*(-164) --45 + j*(-227) --160 + j*(-63) --71 + j*(49) -1 + j*(5) --30 + j*(-38) --71 + j*(-27) --113 + j*(4) --131 + j*(110) -4 + j*(221) -197 + j*(117) -167 + j*(-107) --25 + j*(-143) --84 + j*(-18) --26 + j*(17) --46 + j*(-12) --90 + j*(59) --5 + j*(156) -136 + j*(110) -164 + j*(-22) -103 + j*(-94) -66 + j*(-124) --8 + j*(-197) --194 + j*(-173) --287 + j*(54) --124 + j*(237) -52 + j*(200) -112 + j*(145) -231 + j*(81) -262 + j*(-181) --52 + j*(-349) --326 + j*(-77) --149 + j*(221) -91 + j*(129) -30 + j*(-11) --32 + j*(62) -56 + j*(96) -81 + j*(35) -79 + j*(51) -174 + j*(16) -170 + j*(-146) --2 + j*(-214) --122 + j*(-100) --80 + j*(30) -39 + j*(37) -77 + j*(-76) --37 + j*(-143) --120 + j*(-40) --34 + j*(30) -1 + j*(-59) --99 + j*(-75) --117 + j*(10) --101 + j*(12) --173 + j*(83) --59 + j*(276) -235 + j*(181) -185 + j*(-144) --124 + j*(-111) --71 + j*(191) -264 + j*(134) -277 + j*(-245) --90 + j*(-402) --404 + j*(-138) --311 + j*(268) -90 + j*(347) -272 + j*(21) -45 + j*(-173) --86 + j*(-25) -25 + j*(-8) --83 + j*(-120) --233 + j*(86) -33 + j*(272) -226 + j*(-22) --98 + j*(-202) --271 + j*(151) -78 + j*(340) -279 + j*(57) -95 + j*(-117) --16 + j*(-28) --4 + j*(8) --40 + j*(69) -78 + j*(198) -313 + j*(81) -272 + j*(-214) -9 + j*(-281) --112 + j*(-127) --78 + j*(-23) --30 + j*(23) -56 + j*(36) -119 + j*(-63) -35 + j*(-156) --47 + j*(-92) -40 + j*(-49) -76 + j*(-214) --148 + j*(-326) --365 + j*(-142) --317 + j*(88) --206 + j*(148) --161 + j*(208) --7 + j*(267) -136 + j*(120) -17 + j*(-25) --86 + j*(106) -84 + j*(185) -154 + j*(1) --25 + j*(-38) --8 + j*(156) -233 + j*(115) -233 + j*(-157) -8 + j*(-231) --100 + j*(-129) --130 + j*(-64) --159 + j*(37) --62 + j*(146) -66 + j*(83) -18 + j*(-22) --67 + j*(44) -8 + j*(146) -142 + j*(98) -158 + j*(-36) -64 + j*(-110) --27 + j*(-71) --23 + j*(11) -54 + j*(26) -107 + j*(-57) -52 + j*(-185) --147 + j*(-221) --330 + j*(-16) --221 + j*(300) -131 + j*(345) -312 + j*(74) -192 + j*(-150) -23 + j*(-168) --71 + j*(-105) --102 + j*(1) --19 + j*(91) -97 + j*(45) -91 + j*(-66) -22 + j*(-88) -5 + j*(-83) --33 + j*(-119) --137 + j*(-95) --184 + j*(43) --74 + j*(170) -91 + j*(133) -119 + j*(-13) -25 + j*(-51) -32 + j*(11) -110 + j*(-62) -6 + j*(-186) --143 + j*(-97) --69 + j*(28) -4 + j*(-74) --153 + j*(-144) --278 + j*(28) --190 + j*(209) --28 + j*(267) -151 + j*(206) -205 + j*(-18) --10 + j*(-141) --157 + j*(59) -28 + j*(205) -158 + j*(63) -80 + j*(-13) -98 + j*(9) -91 + j*(-105) --86 + j*(-76) --18 + j*(132) -211 + j*(1) -16 + j*(-245) --234 + j*(1) -52 + j*(231) -251 + j*(-89) --86 + j*(-255) --217 + j*(79) -84 + j*(165) -110 + j*(-91) --110 + j*(-47) --6 + j*(163) -218 + j*(46) -154 + j*(-189) --40 + j*(-220) --156 + j*(-128) --184 + j*(17) --69 + j*(131) -78 + j*(55) -26 + j*(-98) --136 + j*(-69) --156 + j*(100) --10 + j*(195) -146 + j*(112) -135 + j*(-62) --30 + j*(-98) --86 + j*(69) -99 + j*(153) -250 + j*(-33) -122 + j*(-255) --124 + j*(-231) --188 + j*(-32) --55 + j*(51) --4 + j*(-64) --158 + j*(-104) --240 + j*(84) --83 + j*(220) -44 + j*(142) -14 + j*(95) -55 + j*(151) -163 + j*(98) -175 + j*(-11) -154 + j*(-71) -121 + j*(-178) --61 + j*(-245) --223 + j*(-83) --134 + j*(109) -23 + j*(90) -40 + j*(-26) --63 + j*(-75) --184 + j*(28) --112 + j*(262) -214 + j*(273) -328 + j*(-78) -25 + j*(-257) --150 + j*(-34) --2 + j*(88) -49 + j*(14) -53 + j*(50) -209 + j*(-34) -84 + j*(-334) --343 + j*(-233) --317 + j*(254) -139 + j*(308) -239 + j*(-45) -21 + j*(-132) -0 + j*(-38) -14 + j*(-110) --142 + j*(-103) --156 + j*(95) -34 + j*(137) -92 + j*(-17) --23 + j*(-77) --86 + j*(4) --31 + j*(71) -35 + j*(28) --18 + j*(-49) --136 + j*(23) --76 + j*(206) -143 + j*(209) -216 + j*(33) -142 + j*(-41) -165 + j*(-47) -182 + j*(-200) --25 + j*(-333) --278 + j*(-192) --284 + j*(89) --81 + j*(228) -116 + j*(163) -187 + j*(-5) -106 + j*(-158) --52 + j*(-189) --170 + j*(-98) --185 + j*(35) --110 + j*(132) --6 + j*(145) -54 + j*(98) -74 + j*(59) -112 + j*(23) -127 + j*(-89) --16 + j*(-196) --223 + j*(-80) --173 + j*(192) -114 + j*(220) -196 + j*(-34) --5 + j*(-118) --51 + j*(45) -115 + j*(42) -88 + j*(-138) --77 + j*(-112) --34 + j*(0) -28 + j*(-119) --189 + j*(-197) --359 + j*(57) --176 + j*(310) -58 + j*(261) -83 + j*(140) -59 + j*(148) -132 + j*(187) -263 + j*(144) -366 + j*(-21) -301 + j*(-267) -38 + j*(-374) --177 + j*(-218) --143 + j*(-13) -6 + j*(8) -45 + j*(-118) --83 + j*(-208) --263 + j*(-126) --303 + j*(107) --120 + j*(285) -124 + j*(221) -164 + j*(6) -16 + j*(-66) --30 + j*(45) -92 + j*(52) -81 + j*(-104) --105 + j*(-95) --105 + j*(107) -95 + j*(117) -110 + j*(-64) --30 + j*(-69) --7 + j*(24) -49 + j*(-38) --51 + j*(-72) --76 + j*(49) -45 + j*(69) -59 + j*(-28) -1 + j*(-32) -18 + j*(-15) -1 + j*(-49) --28 + j*(1) -68 + j*(8) -63 + j*(-148) --140 + j*(-156) --158 + j*(49) -18 + j*(35) --69 + j*(-136) --291 + j*(12) --151 + j*(303) -156 + j*(231) -154 + j*(-16) -4 + j*(-32) -25 + j*(35) -49 + j*(-44) --81 + j*(-60) --117 + j*(100) -45 + j*(158) -107 + j*(18) --14 + j*(-22) --25 + j*(106) -119 + j*(108) -124 + j*(-33) -1 + j*(-24) -39 + j*(105) -204 + j*(71) -243 + j*(-117) -103 + j*(-262) --107 + j*(-233) --186 + j*(-18) -9 + j*(117) -169 + j*(-78) --38 + j*(-264) --255 + j*(-65) --93 + j*(146) -71 + j*(24) --35 + j*(-64) --45 + j*(53) -103 + j*(7) -45 + j*(-185) --169 + j*(-179) --259 + j*(-13) --221 + j*(146) --75 + j*(259) -122 + j*(190) -117 + j*(1) --24 + j*(11) -30 + j*(129) -163 + j*(53) -115 + j*(-79) -39 + j*(-78) -24 + j*(-94) --67 + j*(-115) --146 + j*(-1) --71 + j*(117) -44 + j*(117) -119 + j*(50) -122 + j*(-75) --22 + j*(-142) --129 + j*(-4) --5 + j*(119) -114 + j*(24) -69 + j*(-62) -50 + j*(-61) -43 + j*(-132) --81 + j*(-155) --127 + j*(-49) --80 + j*(-35) --148 + j*(-53) --191 + j*(80) --61 + j*(153) --11 + j*(72) --51 + j*(94) -46 + j*(123) -75 + j*(-23) --107 + j*(-56) --169 + j*(133) --46 + j*(234) -39 + j*(260) -209 + j*(301) -429 + j*(98) -305 + j*(-234) --11 + j*(-199) --4 + j*(39) -181 + j*(17) -167 + j*(-130) -95 + j*(-141) -110 + j*(-161) -57 + j*(-264) --107 + j*(-279) --221 + j*(-151) --187 + j*(2) --64 + j*(31) --30 + j*(-67) --136 + j*(-105) --219 + j*(-16) --222 + j*(110) --134 + j*(257) -118 + j*(292) -275 + j*(26) -51 + j*(-173) --101 + j*(43) -176 + j*(127) -243 + j*(-247) --187 + j*(-356) --349 + j*(45) --35 + j*(218) -104 + j*(-2) --42 + j*(-104) --130 + j*(-30) --140 + j*(59) --53 + j*(153) -100 + j*(58) --21 + j*(-139) --265 + j*(11) --124 + j*(286) -123 + j*(177) -21 + j*(18) --54 + j*(158) -110 + j*(206) -146 + j*(98) -148 + j*(144) -346 + j*(78) -331 + j*(-241) -21 + j*(-313) --62 + j*(-134) --5 + j*(-163) --192 + j*(-202) --315 + j*(64) --100 + j*(282) -128 + j*(213) -204 + j*(84) -226 + j*(-52) -133 + j*(-189) --13 + j*(-185) --60 + j*(-127) --117 + j*(-110) --192 + j*(11) --81 + j*(163) -76 + j*(117) -71 + j*(33) -98 + j*(65) -218 + j*(-32) -136 + j*(-245) --103 + j*(-230) --140 + j*(-43) --17 + j*(-5) -2 + j*(-107) --103 + j*(-146) --204 + j*(-68) --201 + j*(74) --77 + j*(156) -43 + j*(87) -18 + j*(-26) --78 + j*(-23) --92 + j*(71) --6 + j*(110) -65 + j*(51) -54 + j*(-28) -3 + j*(-69) --63 + j*(-95) --188 + j*(-63) --260 + j*(119) --112 + j*(305) -105 + j*(266) -153 + j*(124) -122 + j*(88) -158 + j*(67) -161 + j*(-8) -119 + j*(-23) -158 + j*(-27) -180 + j*(-141) -59 + j*(-246) --91 + j*(-214) --161 + j*(-121) --182 + j*(-28) --158 + j*(57) --108 + j*(107) --62 + j*(150) -40 + j*(182) -164 + j*(95) -141 + j*(-78) --38 + j*(-122) --150 + j*(40) --28 + j*(221) -210 + j*(173) -235 + j*(-68) -36 + j*(-117) -44 + j*(62) -269 + j*(-25) -148 + j*(-341) --221 + j*(-246) --154 + j*(107) -140 + j*(24) -11 + j*(-214) --194 + j*(-41) --2 + j*(136) -152 + j*(-42) -34 + j*(-159) -0 + j*(-144) --70 + j*(-254) --342 + j*(-173) --310 + j*(194) -59 + j*(204) -55 + j*(-135) --282 + j*(-95) --249 + j*(260) -87 + j*(286) -177 + j*(19) -3 + j*(-105) --130 + j*(-4) --79 + j*(127) -51 + j*(107) -32 + j*(-21) --107 + j*(11) --69 + j*(170) -93 + j*(142) -66 + j*(13) --25 + j*(60) -45 + j*(134) -104 + j*(72) -62 + j*(64) -124 + j*(116) -233 + j*(27) -179 + j*(-120) -54 + j*(-121) -39 + j*(-40) -120 + j*(-28) -174 + j*(-146) -57 + j*(-303) --192 + j*(-267) --262 + j*(-21) --100 + j*(103) --4 + j*(28) --45 + j*(-1) --27 + j*(39) -15 + j*(4) --26 + j*(-27) --45 + j*(16) --8 + j*(23) --14 + j*(3) --22 + j*(30) -24 + j*(40) -49 + j*(-11) -18 + j*(-54) --32 + j*(-62) --83 + j*(-26) --80 + j*(49) --13 + j*(76) -18 + j*(38) -1 + j*(34) -29 + j*(61) -78 + j*(30) -78 + j*(-23) -62 + j*(-53) -33 + j*(-89) --33 + j*(-95) --72 + j*(-38) --35 + j*(1) --16 + j*(-37) --78 + j*(-54) --124 + j*(26) --56 + j*(110) -44 + j*(68) -13 + j*(-25) --82 + j*(21) --27 + j*(143) -125 + j*(108) -138 + j*(-32) -62 + j*(-75) -40 + j*(-86) --35 + j*(-128) --145 + j*(-28) --37 + j*(131) -164 + j*(13) -54 + j*(-241) --240 + j*(-185) --275 + j*(87) --105 + j*(175) --54 + j*(129) --41 + j*(175) -83 + j*(185) -124 + j*(48) -2 + j*(26) -26 + j*(180) -254 + j*(150) -280 + j*(-119) -47 + j*(-206) --38 + j*(-61) -35 + j*(-46) --37 + j*(-86) --65 + j*(52) -115 + j*(58) -78 + j*(-153) --162 + j*(-54) -6 + j*(223) -328 + j*(5) -98 + j*(-344) --228 + j*(-127) --13 + j*(134) -175 + j*(-97) --51 + j*(-226) --109 + j*(-45) -19 + j*(-105) --165 + j*(-229) --330 + j*(17) --105 + j*(196) -25 + j*(25) --117 + j*(-30) --136 + j*(91) --75 + j*(111) --64 + j*(157) -81 + j*(193) -156 + j*(-6) --69 + j*(-76) --107 + j*(180) -178 + j*(200) -199 + j*(-71) --4 + j*(-74) -49 + j*(42) -105 + j*(-75) --48 + j*(-87) --8 + j*(64) -129 + j*(-42) --34 + j*(-173) --140 + j*(16) -51 + j*(69) -30 + j*(-128) --188 + j*(-42) --73 + j*(185) -127 + j*(80) -44 + j*(-42) -45 + j*(36) -153 + j*(-95) --71 + j*(-272) --311 + j*(-13) --74 + j*(242) -141 + j*(32) --62 + j*(-125) --179 + j*(77) --16 + j*(167) -16 + j*(71) --38 + j*(141) -119 + j*(219) -250 + j*(59) -155 + j*(-83) -79 + j*(-50) -105 + j*(-57) -56 + j*(-115) --28 + j*(-63) -15 + j*(38) -155 + j*(28) -233 + j*(-149) -82 + j*(-362) --228 + j*(-315) --295 + j*(-9) --49 + j*(83) --19 + j*(-139) --301 + j*(-110) --281 + j*(252) -97 + j*(297) -186 + j*(-23) --48 + j*(-92) --55 + j*(87) -105 + j*(33) -14 + j*(-136) --166 + j*(-42) --105 + j*(145) -69 + j*(142) -126 + j*(14) -69 + j*(-76) --10 + j*(-82) --33 + j*(-52) --43 + j*(-77) --158 + j*(-76) --227 + j*(112) --27 + j*(276) -199 + j*(119) -109 + j*(-119) --103 + j*(-88) --129 + j*(78) --34 + j*(158) -71 + j*(153) -141 + j*(63) -81 + j*(-21) -36 + j*(50) -183 + j*(53) -187 + j*(-201) --153 + j*(-245) --253 + j*(144) -149 + j*(292) -339 + j*(-86) -25 + j*(-294) --154 + j*(-68) --1 + j*(33) -15 + j*(-88) --103 + j*(-47) --32 + j*(57) -37 + j*(-40) --107 + j*(-82) --166 + j*(107) -23 + j*(222) -186 + j*(107) -190 + j*(-50) -103 + j*(-158) --57 + j*(-165) --136 + j*(8) -44 + j*(134) -214 + j*(-54) -40 + j*(-269) --199 + j*(-137) --110 + j*(89) -91 + j*(24) -50 + j*(-169) --138 + j*(-184) --230 + j*(-40) --163 + j*(98) --31 + j*(94) --35 + j*(-19) --166 + j*(23) --93 + j*(205) -140 + j*(119) -37 + j*(-144) --257 + j*(-19) --130 + j*(305) -187 + j*(207) -112 + j*(-46) --50 + j*(41) -73 + j*(127) -92 + j*(-15) --51 + j*(43) -88 + j*(204) -276 + j*(23) -107 + j*(-150) -25 + j*(11) -241 + j*(-28) -145 + j*(-346) --242 + j*(-277) --223 + j*(87) -62 + j*(66) --9 + j*(-175) --272 + j*(-85) --260 + j*(204) --30 + j*(338) -209 + j*(269) -321 + j*(43) -205 + j*(-158) -29 + j*(-143) -21 + j*(-46) -69 + j*(-63) -43 + j*(-95) -40 + j*(-97) -26 + j*(-156) --83 + j*(-180) --163 + j*(-90) --137 + j*(-2) --98 + j*(28) --65 + j*(42) --40 + j*(33) --45 + j*(40) -2 + j*(71) -71 + j*(3) -12 + j*(-86) --49 + j*(-52) --18 + j*(-75) --158 + j*(-172) --394 + j*(39) --216 + j*(417) -215 + j*(356) -267 + j*(-4) -39 + j*(-91) --21 + j*(19) -14 + j*(40) -23 + j*(61) -95 + j*(56) -98 + j*(-49) -4 + j*(-43) -59 + j*(7) -77 + j*(-148) --192 + j*(-173) --273 + j*(172) -69 + j*(319) -239 + j*(54) -88 + j*(-60) -86 + j*(-1) -102 + j*(-127) --129 + j*(-129) --141 + j*(173) -198 + j*(213) -281 + j*(-101) -58 + j*(-202) -4 + j*(-91) -53 + j*(-126) --39 + j*(-185) --129 + j*(-119) --148 + j*(-39) --126 + j*(63) -30 + j*(96) -95 + j*(-108) --163 + j*(-204) --314 + j*(91) --50 + j*(296) -163 + j*(134) -129 + j*(0) -139 + j*(-59) -47 + j*(-234) --250 + j*(-158) --202 + j*(202) -178 + j*(155) -110 + j*(-235) --288 + j*(-155) --218 + j*(224) -96 + j*(153) --20 + j*(-86) --237 + j*(98) --28 + j*(359) -277 + j*(214) -241 + j*(-70) -39 + j*(-107) --6 + j*(23) -114 + j*(50) -146 + j*(-100) --25 + j*(-165) --116 + j*(1) -40 + j*(86) -90 + j*(-74) --91 + j*(-78) --48 + j*(143) -234 + j*(71) -175 + j*(-279) --200 + j*(-285) --286 + j*(40) --75 + j*(151) --17 + j*(57) --71 + j*(105) -59 + j*(202) -235 + j*(68) -175 + j*(-158) --39 + j*(-190) --136 + j*(-37) --61 + j*(75) -27 + j*(76) -87 + j*(53) -165 + j*(-28) -125 + j*(-212) --119 + j*(-264) --262 + j*(-40) --106 + j*(139) -42 + j*(45) --30 + j*(-46) --74 + j*(23) --8 + j*(40) --19 + j*(-18) --76 + j*(11) --53 + j*(69) --13 + j*(94) -71 + j*(114) -192 + j*(-9) -81 + j*(-239) --222 + j*(-189) --243 + j*(119) -6 + j*(170) -20 + j*(-16) --153 + j*(39) --67 + j*(248) -168 + j*(204) -190 + j*(6) -79 + j*(-42) -55 + j*(11) -116 + j*(11) -151 + j*(-91) -37 + j*(-217) --189 + j*(-141) --180 + j*(150) -139 + j*(216) -272 + j*(-98) -0 + j*(-273) --162 + j*(-72) --13 + j*(18) --18 + j*(-144) --253 + j*(-80) --201 + j*(224) -119 + j*(223) -158 + j*(-62) --76 + j*(-111) --123 + j*(72) --8 + j*(115) -5 + j*(85) -42 + j*(146) -187 + j*(103) -190 + j*(-75) -51 + j*(-117) -18 + j*(-45) -43 + j*(-53) -4 + j*(-48) -48 + j*(8) -132 + j*(-81) -28 + j*(-197) --75 + j*(-110) -22 + j*(-79) --21 + j*(-257) --312 + j*(-221) --363 + j*(127) --65 + j*(267) -102 + j*(74) -8 + j*(-53) --57 + j*(-21) --49 + j*(-23) --98 + j*(-45) --168 + j*(1) --192 + j*(103) --134 + j*(218) -10 + j*(260) -124 + j*(185) -151 + j*(85) -132 + j*(1) -42 + j*(-52) --50 + j*(34) -49 + j*(156) -209 + j*(53) -132 + j*(-117) -2 + j*(-72) -53 + j*(-21) -35 + j*(-124) --127 + j*(-79) --94 + j*(112) -71 + j*(101) -65 + j*(6) -58 + j*(45) -162 + j*(-21) -55 + j*(-196) --175 + j*(-70) --47 + j*(199) -252 + j*(92) -190 + j*(-209) --69 + j*(-199) --71 + j*(-8) -73 + j*(-34) -11 + j*(-181) --168 + j*(-110) --112 + j*(105) -133 + j*(71) -139 + j*(-204) --138 + j*(-275) --276 + j*(-60) --179 + j*(93) --94 + j*(119) -18 + j*(148) -162 + j*(6) -26 + j*(-228) --247 + j*(-132) --196 + j*(110) --56 + j*(52) --201 + j*(25) --186 + j*(303) -185 + j*(322) -255 + j*(-55) --76 + j*(-139) --141 + j*(135) -88 + j*(190) -140 + j*(19) -35 + j*(-28) --6 + j*(30) -34 + j*(95) -163 + j*(86) -219 + j*(-117) --15 + j*(-264) --230 + j*(-56) --86 + j*(169) -83 + j*(84) -21 + j*(7) -28 + j*(96) -162 + j*(54) -146 + j*(-94) -45 + j*(-119) -13 + j*(-106) --49 + j*(-112) --103 + j*(-21) --24 + j*(58) -58 + j*(6) -44 + j*(-64) --5 + j*(-103) --108 + j*(-93) --155 + j*(63) -35 + j*(171) -190 + j*(-23) -7 + j*(-206) --175 + j*(-45) --35 + j*(121) -113 + j*(-3) -18 + j*(-146) --119 + j*(-103) --148 + j*(11) --88 + j*(97) -18 + j*(88) -26 + j*(-2) --47 + j*(23) -50 + j*(112) -197 + j*(-47) -23 + j*(-272) --256 + j*(-141) --197 + j*(119) --28 + j*(103) --75 + j*(49) --61 + j*(182) -146 + j*(168) -223 + j*(-352) --117 + j*(-362) --214 + j*(-116) --118 + j*(-18) --79 + j*(3) -4 + j*(16) -34 + j*(-110) --133 + j*(-130) --123 + j*(67) -101 + j*(-2) --35 + j*(-277) --377 + j*(-114) --243 + j*(260) -86 + j*(173) -13 + j*(-74) --164 + j*(1) --120 + j*(128) --76 + j*(166) -41 + j*(252) -271 + j*(109) -152 + j*(-218) --205 + j*(-132) --139 + j*(202) -138 + j*(141) -63 + j*(-48) --29 + j*(73) -163 + j*(103) -194 + j*(-156) --71 + j*(-252) --256 + j*(-65) --218 + j*(179) -21 + j*(313) -284 + j*(127) -158 + j*(-184) --140 + j*(-66) -32 + j*(200) -288 + j*(-52) --25 + j*(-322) --303 + j*(11) -8 + j*(266) -199 + j*(1) --21 + j*(-95) --13 + j*(100) -170 + j*(16) -52 + j*(-146) --64 + j*(-15) -80 + j*(44) -100 + j*(-100) --12 + j*(-95) -40 + j*(-29) -87 + j*(-139) --32 + j*(-217) --127 + j*(-185) --219 + j*(-163) --351 + j*(-13) --260 + j*(244) -8 + j*(251) -52 + j*(61) --82 + j*(55) --55 + j*(198) -103 + j*(207) -172 + j*(102) -163 + j*(34) -175 + j*(-6) -187 + j*(-92) -112 + j*(-191) --13 + j*(-187) --48 + j*(-117) --37 + j*(-129) --129 + j*(-146) --194 + j*(-21) --95 + j*(64) --56 + j*(-2) --133 + j*(26) --59 + j*(139) -74 + j*(41) --53 + j*(-100) --219 + j*(56) --78 + j*(266) -144 + j*(188) -136 + j*(12) -25 + j*(2) -35 + j*(95) -173 + j*(95) -249 + j*(-93) -69 + j*(-274) --174 + j*(-158) --117 + j*(83) -91 + j*(48) -60 + j*(-139) --109 + j*(-133) --146 + j*(-28) --153 + j*(18) --174 + j*(133) --21 + j*(262) -191 + j*(147) -131 + j*(-84) --91 + j*(-60) --91 + j*(168) -141 + j*(219) -254 + j*(37) -179 + j*(-83) -151 + j*(-97) -132 + j*(-204) --59 + j*(-262) --197 + j*(-70) --52 + j*(82) -57 + j*(-21) --24 + j*(-64) -4 + j*(2) -58 + j*(-95) --100 + j*(-137) --112 + j*(71) -148 + j*(45) -110 + j*(-274) --224 + j*(-282) --287 + j*(-44) --231 + j*(-8) --341 + j*(89) --217 + j*(372) -134 + j*(326) -149 + j*(50) -1 + j*(65) -110 + j*(130) -159 + j*(-41) --1 + j*(-98) --35 + j*(-6) --40 + j*(-34) --161 + j*(46) --49 + j*(272) -239 + j*(190) -215 + j*(-86) -18 + j*(-94) -22 + j*(13) -71 + j*(-9) -58 + j*(-19) -90 + j*(-33) -60 + j*(-100) --13 + j*(-57) -71 + j*(-2) -117 + j*(-132) --30 + j*(-194) --86 + j*(-75) --5 + j*(-81) --77 + j*(-177) --211 + j*(-114) --216 + j*(12) --179 + j*(95) --92 + j*(181) -43 + j*(148) -42 + j*(47) -11 + j*(85) -128 + j*(83) -135 + j*(-89) --26 + j*(-108) --13 + j*(-4) -34 + j*(-100) --165 + j*(-124) --202 + j*(153) -97 + j*(221) -173 + j*(-41) --33 + j*(-90) --23 + j*(67) -114 + j*(-3) -16 + j*(-141) --141 + j*(-59) --120 + j*(104) -6 + j*(171) -139 + j*(124) -180 + j*(-7) -117 + j*(-78) -108 + j*(-89) -84 + j*(-193) --108 + j*(-221) --190 + j*(-8) -10 + j*(79) -62 + j*(-123) --175 + j*(-160) --235 + j*(95) --3 + j*(199) -134 + j*(30) -48 + j*(-132) --129 + j*(-153) --287 + j*(-12) --277 + j*(249) --39 + j*(432) -274 + j*(365) -433 + j*(85) -322 + j*(-204) -59 + j*(-260) --57 + j*(-103) -18 + j*(-27) -33 + j*(-77) --15 + j*(-50) -49 + j*(-8) -103 + j*(-109) -4 + j*(-202) --118 + j*(-167) --178 + j*(-77) --171 + j*(42) --45 + j*(113) -62 + j*(-1) --47 + j*(-123) --185 + j*(-22) --116 + j*(124) -4 + j*(99) -1 + j*(15) --64 + j*(18) --69 + j*(95) -28 + j*(132) -93 + j*(33) --4 + j*(-34) --49 + j*(76) -84 + j*(90) -58 + j*(-60) --105 + j*(33) -72 + j*(223) -306 + j*(-32) -3 + j*(-308) --298 + j*(17) -28 + j*(320) -315 + j*(13) -51 + j*(-237) --146 + j*(-25) --1 + j*(113) -62 + j*(49) -73 + j*(97) -251 + j*(71) -310 + j*(-189) -95 + j*(-368) --134 + j*(-315) --258 + j*(-168) --263 + j*(39) --74 + j*(165) -98 + j*(18) --33 + j*(-171) --260 + j*(-57) --216 + j*(215) -39 + j*(288) -199 + j*(135) -175 + j*(-11) -128 + j*(-47) -139 + j*(-87) -107 + j*(-184) --12 + j*(-233) --125 + j*(-194) --191 + j*(-104) --168 + j*(8) --58 + j*(2) --112 + j*(-141) --364 + j*(-62) --354 + j*(296) --7 + j*(395) -122 + j*(168) -4 + j*(133) -89 + j*(241) -245 + j*(127) -202 + j*(-16) -177 + j*(-44) -158 + j*(-179) --78 + j*(-233) --194 + j*(-3) --25 + j*(98) --21 + j*(-19) --141 + j*(86) -23 + j*(247) -190 + j*(107) -105 + j*(16) -142 + j*(83) -241 + j*(-56) -65 + j*(-168) -5 + j*(20) -246 + j*(1) -198 + j*(-315) --134 + j*(-306) --176 + j*(-57) --74 + j*(-21) --92 + j*(25) -76 + j*(118) -253 + j*(-148) --59 + j*(-423) --412 + j*(-146) --233 + j*(209) -33 + j*(124) --13 + j*(-18) --54 + j*(36) -2 + j*(25) --38 + j*(-10) --30 + j*(65) -95 + j*(10) -16 + j*(-184) --251 + j*(-123) --256 + j*(179) -20 + j*(262) -134 + j*(60) -3 + j*(-25) --24 + j*(76) -87 + j*(51) -25 + j*(-78) --124 + j*(8) --28 + j*(175) -152 + j*(83) -81 + j*(-86) --64 + j*(-41) --49 + j*(65) --4 + j*(88) -44 + j*(122) -156 + j*(86) -158 + j*(-56) -40 + j*(-72) -57 + j*(4) -123 + j*(-68) -23 + j*(-143) --40 + j*(-57) -34 + j*(-45) --11 + j*(-144) --154 + j*(-81) --125 + j*(83) -10 + j*(102) -62 + j*(28) -48 + j*(-32) --8 + j*(-69) --83 + j*(-17) --49 + j*(91) -76 + j*(95) -133 + j*(-16) -76 + j*(-117) --46 + j*(-124) --100 + j*(-6) -15 + j*(78) -121 + j*(-42) -18 + j*(-172) --105 + j*(-120) --112 + j*(-68) --171 + j*(-49) --202 + j*(98) --40 + j*(182) -48 + j*(47) --74 + j*(1) --91 + j*(130) -13 + j*(153) -28 + j*(134) -112 + j*(191) -283 + j*(66) -190 + j*(-181) --50 + j*(-140) --25 + j*(47) -116 + j*(8) -77 + j*(-105) --1 + j*(-88) --8 + j*(-64) --26 + j*(-51) --6 + j*(-22) -13 + j*(-75) --98 + j*(-91) --134 + j*(87) -96 + j*(171) -262 + j*(-78) -49 + j*(-341) --283 + j*(-235) --309 + j*(95) --49 + j*(218) -96 + j*(40) --30 + j*(-72) --94 + j*(37) -9 + j*(51) --33 + j*(-47) --124 + j*(53) -39 + j*(127) -79 + j*(-116) --263 + j*(-139) --325 + j*(289) -103 + j*(416) -244 + j*(88) -29 + j*(35) -117 + j*(213) -332 + j*(40) -176 + j*(-206) --27 + j*(-109) -34 + j*(4) -69 + j*(-52) -26 + j*(-38) -86 + j*(-21) -98 + j*(-133) --35 + j*(-187) --146 + j*(-99) --163 + j*(30) --75 + j*(153) -102 + j*(144) -151 + j*(-22) -29 + j*(-74) -21 + j*(30) -142 + j*(8) -147 + j*(-128) -60 + j*(-193) --25 + j*(-213) --138 + j*(-165) --137 + j*(-36) --25 + j*(-57) --117 + j*(-185) --313 + j*(-41) --186 + j*(215) -73 + j*(129) -10 + j*(-91) --188 + j*(-33) --156 + j*(150) --1 + j*(170) -66 + j*(65) -9 + j*(-28) --105 + j*(-4) --117 + j*(129) -7 + j*(177) -62 + j*(92) -2 + j*(70) --1 + j*(146) -91 + j*(202) -249 + j*(173) -368 + j*(-40) -200 + j*(-308) --124 + j*(-233) --95 + j*(58) -148 + j*(-4) -25 + j*(-247) --243 + j*(-95) --110 + j*(173) -111 + j*(69) -13 + j*(-80) --71 + j*(30) -45 + j*(75) -62 + j*(-25) --4 + j*(-7) -66 + j*(32) -112 + j*(-86) --21 + j*(-180) --173 + j*(-95) --192 + j*(79) --62 + j*(213) -132 + j*(177) -175 + j*(3) -57 + j*(-47) -61 + j*(55) -217 + j*(21) -240 + j*(-191) -69 + j*(-334) --145 + j*(-303) --267 + j*(-139) --214 + j*(37) --87 + j*(57) --81 + j*(0) --100 + j*(49) --11 + j*(47) --57 + j*(-75) --234 + j*(18) --134 + j*(261) -125 + j*(190) -74 + j*(-13) --49 + j*(70) -92 + j*(134) -115 + j*(-39) --58 + j*(3) -84 + j*(188) -326 + j*(-57) -28 + j*(-380) --365 + j*(-95) --148 + j*(321) -235 + j*(210) -224 + j*(-69) -118 + j*(-110) -112 + j*(-178) --54 + j*(-281) --257 + j*(-122) --157 + j*(101) -25 + j*(32) --56 + j*(-122) --231 + j*(-43) --213 + j*(147) --79 + j*(205) --19 + j*(182) -27 + j*(203) -136 + j*(184) -176 + j*(63) -98 + j*(25) -138 + j*(98) -284 + j*(-20) -152 + j*(-266) --157 + j*(-163) --75 + j*(167) -272 + j*(98) -243 + j*(-262) --79 + j*(-310) --180 + j*(-104) --121 + j*(-22) --129 + j*(17) --73 + j*(122) -73 + j*(115) -127 + j*(-4) -89 + j*(-89) -13 + j*(-136) --88 + j*(-99) --75 + j*(14) -24 + j*(-11) --43 + j*(-105) --148 + j*(16) -12 + j*(148) -184 + j*(-37) -13 + j*(-256) --235 + j*(-158) --253 + j*(63) --132 + j*(175) -7 + j*(188) -121 + j*(86) -82 + j*(-61) --48 + j*(-65) --71 + j*(22) --37 + j*(45) --30 + j*(61) -25 + j*(79) -67 + j*(5) --13 + j*(-47) --65 + j*(34) -18 + j*(83) -67 + j*(-1) --18 + j*(-66) --122 + j*(-3) --121 + j*(146) -42 + j*(250) -243 + j*(139) -220 + j*(-100) -18 + j*(-141) --32 + j*(-6) -63 + j*(11) -41 + j*(-72) --39 + j*(-31) -7 + j*(40) -64 + j*(-4) -33 + j*(-47) -13 + j*(-38) --11 + j*(-57) --86 + j*(-13) --52 + j*(140) -160 + j*(158) -261 + j*(-52) -122 + j*(-205) -4 + j*(-161) -17 + j*(-146) --57 + j*(-216) --218 + j*(-132) --185 + j*(71) -6 + j*(81) -26 + j*(-89) --151 + j*(-119) --225 + j*(56) --95 + j*(184) -45 + j*(132) -45 + j*(26) --18 + j*(23) -0 + j*(76) -54 + j*(44) -15 + j*(1) --4 + j*(78) -135 + j*(101) -208 + j*(-83) -43 + j*(-216) --100 + j*(-126) --80 + j*(-51) --107 + j*(-56) --152 + j*(42) --45 + j*(132) -49 + j*(54) -0 + j*(1) -0 + j*(45) -58 + j*(7) -15 + j*(-72) --64 + j*(-62) --104 + j*(-23) --142 + j*(49) --80 + j*(156) -31 + j*(118) --28 + j*(48) --75 + j*(192) -141 + j*(274) -272 + j*(69) -136 + j*(-35) -148 + j*(63) -301 + j*(-52) -177 + j*(-295) --89 + j*(-259) --163 + j*(-65) --95 + j*(74) -64 + j*(137) -232 + j*(-18) -102 + j*(-238) --108 + j*(-122) -47 + j*(31) -162 + j*(-208) --146 + j*(-344) --315 + j*(-50) --107 + j*(96) --50 + j*(-24) --119 + j*(23) --1 + j*(54) --10 + j*(-113) --206 + j*(-80) --172 + j*(90) --112 + j*(31) --278 + j*(105) --152 + j*(428) -272 + j*(356) -274 + j*(-40) --8 + j*(-49) -43 + j*(140) -188 + j*(39) -100 + j*(-66) -71 + j*(-19) -104 + j*(-89) --40 + j*(-136) --99 + j*(35) -70 + j*(86) -100 + j*(-71) --41 + j*(-81) --35 + j*(41) -64 + j*(29) -54 + j*(-48) -4 + j*(-39) -16 + j*(-15) -30 + j*(-28) -23 + j*(-38) -37 + j*(-33) -69 + j*(-82) -5 + j*(-177) --146 + j*(-139) --141 + j*(26) -6 + j*(3) --82 + j*(-157) --302 + j*(-16) --176 + j*(260) -77 + j*(187) -21 + j*(42) -0 + j*(155) -213 + j*(106) -161 + j*(-171) --105 + j*(-142) --74 + j*(41) --6 + j*(-48) --200 + j*(-20) --127 + j*(281) -233 + j*(215) -174 + j*(-139) --139 + j*(-53) --16 + j*(238) -275 + j*(110) -204 + j*(-158) -18 + j*(-156) --12 + j*(-95) --54 + j*(-97) --115 + j*(-15) --56 + j*(88) -47 + j*(91) -103 + j*(29) -100 + j*(-44) -52 + j*(-76) -48 + j*(-64) -62 + j*(-144) --107 + j*(-223) --295 + j*(-20) --124 + j*(269) -211 + j*(180) -210 + j*(-136) --30 + j*(-187) --75 + j*(-37) -23 + j*(-43) --26 + j*(-152) --160 + j*(-112) --173 + j*(-1) --141 + j*(27) --179 + j*(72) --134 + j*(211) -62 + j*(235) -153 + j*(57) -18 + j*(-49) --91 + j*(59) --9 + j*(190) -154 + j*(190) -287 + j*(50) -264 + j*(-194) --6 + j*(-338) --285 + j*(-137) --204 + j*(201) -122 + j*(242) -264 + j*(-21) -90 + j*(-225) --133 + j*(-137) --104 + j*(73) -94 + j*(60) -81 + j*(-141) --124 + j*(-130) --107 + j*(52) -30 + j*(-14) --123 + j*(-132) --267 + j*(105) --4 + j*(286) -173 + j*(42) --68 + j*(-75) --126 + j*(203) -191 + j*(258) -284 + j*(-37) -79 + j*(-140) -24 + j*(-43) -53 + j*(-62) --16 + j*(-51) -40 + j*(43) -168 + j*(-70) -23 + j*(-254) --206 + j*(-125) --115 + j*(107) -86 + j*(30) --8 + j*(-153) --216 + j*(-48) --146 + j*(204) -122 + j*(213) -206 + j*(-9) -70 + j*(-124) --12 + j*(-57) -35 + j*(-30) -35 + j*(-92) --35 + j*(-102) --54 + j*(-55) --30 + j*(-59) --64 + j*(-103) --161 + j*(-87) --221 + j*(37) --135 + j*(186) -44 + j*(175) -94 + j*(25) -1 + j*(-35) --40 + j*(4) --54 + j*(4) --107 + j*(71) -4 + j*(193) -194 + j*(51) -24 + j*(-204) --309 + j*(-17) --148 + j*(399) -307 + j*(319) -320 + j*(-84) -30 + j*(-134) -13 + j*(58) -161 + j*(40) -166 + j*(-69) -151 + j*(-122) -107 + j*(-256) --153 + j*(-310) --333 + j*(-22) --107 + j*(238) -148 + j*(95) -56 + j*(-95) --53 + j*(-16) -44 + j*(20) -18 + j*(-106) --148 + j*(-36) --59 + j*(171) -180 + j*(93) -134 + j*(-147) --69 + j*(-138) --74 + j*(8) -19 + j*(6) -6 + j*(-56) --35 + j*(-47) --35 + j*(-32) --45 + j*(-34) --56 + j*(-30) --88 + j*(-30) --137 + j*(29) --98 + j*(129) -4 + j*(142) -40 + j*(108) -86 + j*(119) -192 + j*(45) -163 + j*(-137) --23 + j*(-178) --109 + j*(-47) --45 + j*(38) -23 + j*(16) -29 + j*(-38) --18 + j*(-78) --82 + j*(-54) --97 + j*(-8) --124 + j*(24) --136 + j*(148) -54 + j*(250) -238 + j*(50) -54 + j*(-159) --132 + j*(24) -81 + j*(172) -197 + j*(-84) --91 + j*(-178) --169 + j*(130) -138 + j*(212) -238 + j*(-50) -71 + j*(-148) -27 + j*(-93) -21 + j*(-141) --101 + j*(-151) --175 + j*(-35) --143 + j*(88) --20 + j*(175) -168 + j*(91) -126 + j*(-157) --150 + j*(-144) --145 + j*(139) -122 + j*(133) -107 + j*(-90) --35 + j*(-45) -81 + j*(3) -63 + j*(-230) --289 + j*(-218) --350 + j*(189) -14 + j*(330) -170 + j*(72) --1 + j*(-24) --21 + j*(124) -160 + j*(117) -177 + j*(-96) --41 + j*(-163) --151 + j*(40) -27 + j*(177) -166 + j*(32) -45 + j*(-67) -13 + j*(75) -225 + j*(71) -252 + j*(-197) -13 + j*(-288) --76 + j*(-163) --52 + j*(-177) --203 + j*(-203) --318 + j*(5) --170 + j*(200) -23 + j*(168) -77 + j*(37) -5 + j*(-57) --119 + j*(-8) --84 + j*(159) -120 + j*(156) -163 + j*(-39) -38 + j*(-105) -2 + j*(-85) --69 + j*(-130) --208 + j*(-8) --69 + j*(190) -144 + j*(28) --67 + j*(-190) --315 + j*(65) --78 + j*(351) -194 + j*(199) -129 + j*(35) -116 + j*(79) -212 + j*(-13) -105 + j*(-165) --42 + j*(-103) --18 + j*(-26) --33 + j*(-53) --98 + j*(36) -28 + j*(151) -187 + j*(27) -95 + j*(-152) --76 + j*(-102) --53 + j*(45) -81 + j*(30) -79 + j*(-110) --73 + j*(-139) --142 + j*(-1) --56 + j*(91) -11 + j*(70) -44 + j*(74) -137 + j*(27) -115 + j*(-141) --91 + j*(-153) --125 + j*(53) -66 + j*(93) -107 + j*(-72) --11 + j*(-115) --41 + j*(-74) --77 + j*(-88) --153 + j*(-8) --74 + j*(104) -13 + j*(44) --59 + j*(32) -12 + j*(166) -238 + j*(53) -144 + j*(-252) --177 + j*(-214) --190 + j*(52) --13 + j*(71) --35 + j*(-33) --102 + j*(30) --28 + j*(89) -14 + j*(33) --23 + j*(18) --9 + j*(43) -12 + j*(16) --22 + j*(-2) --42 + j*(20) --49 + j*(36) --61 + j*(78) --13 + j*(137) -71 + j*(127) -106 + j*(69) -105 + j*(23) -86 + j*(-14) -47 + j*(-19) -42 + j*(12) -81 + j*(4) -81 + j*(-41) -54 + j*(-64) -29 + j*(-87) --44 + j*(-96) --117 + j*(-6) --57 + j*(128) -97 + j*(144) -198 + j*(35) -192 + j*(-114) -61 + j*(-221) --120 + j*(-144) --91 + j*(68) -144 + j*(69) -187 + j*(-185) --45 + j*(-290) --186 + j*(-134) --126 + j*(-23) --78 + j*(-33) --77 + j*(-47) --109 + j*(-83) --236 + j*(-37) --226 + j*(202) -79 + j*(271) -223 + j*(-45) --52 + j*(-234) --246 + j*(-39) --148 + j*(95) --148 + j*(66) --197 + j*(212) -18 + j*(345) -206 + j*(161) -88 + j*(6) -4 + j*(106) -112 + j*(158) -176 + j*(88) -209 + j*(41) -247 + j*(-77) -134 + j*(-211) --4 + j*(-175) --25 + j*(-144) --153 + j*(-154) --265 + j*(98) -23 + j*(327) -317 + j*(71) -131 + j*(-193) --20 + j*(-42) -173 + j*(-32) -96 + j*(-317) --264 + j*(-239) --225 + j*(116) -62 + j*(96) -35 + j*(-115) --110 + j*(-95) --129 + j*(-40) --211 + j*(5) --209 + j*(233) -86 + j*(327) -258 + j*(68) -91 + j*(-89) -32 + j*(23) -170 + j*(-24) -79 + j*(-250) --222 + j*(-204) --284 + j*(109) --35 + j*(264) -156 + j*(127) -106 + j*(-33) -9 + j*(1) -76 + j*(74) -187 + j*(-17) -138 + j*(-182) --18 + j*(-234) --148 + j*(-174) --220 + j*(-49) --185 + j*(90) --85 + j*(149) --6 + j*(161) -112 + j*(158) -230 + j*(0) -107 + j*(-209) --117 + j*(-146) --82 + j*(18) --1 + j*(-53) --151 + j*(-81) --170 + j*(132) -49 + j*(147) -28 + j*(-42) --135 + j*(54) -24 + j*(213) -176 + j*(22) --32 + j*(-86) --86 + j*(156) -201 + j*(181) -238 + j*(-119) --22 + j*(-173) --73 + j*(19) -60 + j*(59) -112 + j*(-21) -105 + j*(-103) -6 + j*(-199) --177 + j*(-119) --129 + j*(101) -83 + j*(54) --2 + j*(-140) --205 + j*(7) --2 + j*(243) -291 + j*(10) -77 + j*(-358) --356 + j*(-235) --397 + j*(187) --103 + j*(388) -156 + j*(310) -265 + j*(131) -234 + j*(-39) -114 + j*(-98) -68 + j*(-42) -121 + j*(-46) -118 + j*(-134) -43 + j*(-175) --6 + j*(-183) --94 + j*(-211) --239 + j*(-127) --238 + j*(78) --62 + j*(156) -25 + j*(55) --22 + j*(17) --8 + j*(59) -60 + j*(25) -52 + j*(-66) --31 + j*(-122) --165 + j*(-97) --246 + j*(84) --81 + j*(274) -169 + j*(173) -129 + j*(-61) --41 + j*(-42) --1 + j*(53) -28 + j*(-37) --127 + j*(-18) --95 + j*(196) -140 + j*(185) -142 + j*(-6) -23 + j*(27) -132 + j*(103) -218 + j*(-57) -79 + j*(-162) -8 + j*(-87) -34 + j*(-99) --49 + j*(-119) --70 + j*(-13) -31 + j*(-25) --42 + j*(-132) --174 + j*(-13) --49 + j*(132) -66 + j*(23) --40 + j*(-21) --6 + j*(108) -163 + j*(21) -55 + j*(-175) --128 + j*(-65) --13 + j*(71) -65 + j*(-69) --99 + j*(-96) --74 + j*(76) -100 + j*(-28) --100 + j*(-233) --386 + j*(34) --129 + j*(409) -279 + j*(222) -163 + j*(-144) --134 + j*(-53) --40 + j*(199) -188 + j*(122) -153 + j*(-63) -43 + j*(-46) -86 + j*(-2) -121 + j*(-87) -28 + j*(-152) --52 + j*(-89) --8 + j*(-25) -50 + j*(-85) --23 + j*(-180) --165 + j*(-146) --204 + j*(-16) --154 + j*(54) --144 + j*(88) --98 + j*(173) -43 + j*(182) -98 + j*(55) -8 + j*(6) --11 + j*(95) -104 + j*(115) -175 + j*(6) -135 + j*(-130) --28 + j*(-204) --218 + j*(-63) --127 + j*(205) -177 + j*(165) -170 + j*(-130) --81 + j*(-122) --25 + j*(62) -99 + j*(-93) --175 + j*(-198) --305 + j*(164) -71 + j*(327) -210 + j*(6) --46 + j*(-25) -81 + j*(217) -372 + j*(-47) -49 + j*(-410) --353 + j*(-103) --105 + j*(274) -185 + j*(89) -45 + j*(-71) -21 + j*(68) -194 + j*(-9) -76 + j*(-224) --145 + j*(-120) --81 + j*(67) -43 + j*(45) -63 + j*(8) -141 + j*(-40) -125 + j*(-245) --159 + j*(-333) --387 + j*(-76) --262 + j*(242) -52 + j*(285) -228 + j*(51) -97 + j*(-194) --165 + j*(-156) --192 + j*(86) -6 + j*(148) -72 + j*(6) --21 + j*(-44) --42 + j*(8) --21 + j*(-8) --69 + j*(-26) --122 + j*(25) --125 + j*(115) --47 + j*(216) -127 + j*(212) -209 + j*(37) -93 + j*(-69) -43 + j*(0) -126 + j*(-35) -35 + j*(-187) --184 + j*(-109) --168 + j*(132) -25 + j*(175) -89 + j*(71) -62 + j*(46) -91 + j*(54) -129 + j*(8) -129 + j*(-59) -84 + j*(-127) --25 + j*(-149) --112 + j*(-56) --74 + j*(61) -32 + j*(75) -75 + j*(9) -45 + j*(-30) -35 + j*(-6) -99 + j*(-19) -99 + j*(-148) --78 + j*(-198) --180 + j*(-15) --16 + j*(105) -88 + j*(-45) --67 + j*(-121) --122 + j*(45) -47 + j*(96) -112 + j*(-54) -18 + j*(-138) --59 + j*(-147) --173 + j*(-126) --249 + j*(50) --78 + j*(206) -102 + j*(76) -4 + j*(-79) --115 + j*(8) --25 + j*(96) -45 + j*(4) --52 + j*(-67) --154 + j*(13) --117 + j*(154) -38 + j*(181) -104 + j*(40) --29 + j*(-26) --80 + j*(121) -78 + j*(172) -119 + j*(44) -52 + j*(59) -178 + j*(81) -203 + j*(-158) --105 + j*(-211) --176 + j*(105) -100 + j*(158) -86 + j*(-57) --78 + j*(70) -170 + j*(234) -381 + j*(-73) -115 + j*(-324) --103 + j*(-158) --21 + j*(-47) --13 + j*(-86) --24 + j*(-48) -26 + j*(-95) --98 + j*(-156) --170 + j*(23) -34 + j*(74) -33 + j*(-156) --228 + j*(-105) --163 + j*(162) -49 + j*(91) --55 + j*(-23) --78 + j*(143) -136 + j*(117) -88 + j*(-100) --74 + j*(-24) -45 + j*(58) -47 + j*(-107) --160 + j*(-49) --60 + j*(171) -133 + j*(49) --1 + j*(-78) --38 + j*(78) -146 + j*(24) -27 + j*(-180) --169 + j*(-9) -54 + j*(150) -183 + j*(-133) --143 + j*(-261) --291 + j*(56) --34 + j*(204) -76 + j*(14) --81 + j*(-49) --136 + j*(98) --8 + j*(189) -109 + j*(116) -85 + j*(4) --1 + j*(27) -54 + j*(110) -161 + j*(28) -81 + j*(-88) --9 + j*(-13) -81 + j*(32) -89 + j*(-84) --42 + j*(-56) -25 + j*(90) -211 + j*(2) -165 + j*(-228) --50 + j*(-291) --224 + j*(-180) --269 + j*(36) --84 + j*(199) -123 + j*(67) -13 + j*(-132) --170 + j*(-20) --52 + j*(141) -76 + j*(28) --49 + j*(-59) --116 + j*(81) -17 + j*(170) -146 + j*(95) -168 + j*(-48) -49 + j*(-161) --111 + j*(-78) --35 + j*(81) -108 + j*(-36) --85 + j*(-177) --255 + j*(91) -52 + j*(313) -323 + j*(22) -112 + j*(-261) --116 + j*(-156) --99 + j*(-52) --137 + j*(-53) --193 + j*(76) --76 + j*(194) -32 + j*(173) -106 + j*(176) -270 + j*(93) -274 + j*(-181) -8 + j*(-296) --151 + j*(-134) --101 + j*(-42) --129 + j*(-54) --191 + j*(64) --76 + j*(199) -84 + j*(156) -115 + j*(51) -105 + j*(1) -103 + j*(-62) -23 + j*(-135) --111 + j*(-93) --134 + j*(71) -18 + j*(165) -168 + j*(69) -170 + j*(-89) -86 + j*(-190) --62 + j*(-257) --286 + j*(-156) --298 + j*(162) -30 + j*(271) -175 + j*(-34) --128 + j*(-179) --298 + j*(134) --25 + j*(361) -221 + j*(213) -233 + j*(49) -245 + j*(-49) -184 + j*(-243) --98 + j*(-312) --303 + j*(-71) --190 + j*(200) -52 + j*(226) -160 + j*(67) -76 + j*(-42) -1 + j*(37) -141 + j*(112) -286 + j*(-86) -103 + j*(-325) --180 + j*(-226) --165 + j*(12) --15 + j*(30) --6 + j*(-50) --42 + j*(-57) --66 + j*(-71) --141 + j*(-52) --167 + j*(64) --81 + j*(138) --5 + j*(130) -53 + j*(117) -122 + j*(42) -70 + j*(-81) --72 + j*(-55) --62 + j*(87) -76 + j*(93) -98 + j*(-37) --18 + j*(-68) --57 + j*(47) -69 + j*(101) -165 + j*(-36) -36 + j*(-178) --132 + j*(-77) --51 + j*(88) -105 + j*(7) -21 + j*(-148) --135 + j*(-89) --132 + j*(34) --95 + j*(84) --34 + j*(168) -147 + j*(148) -190 + j*(-71) --7 + j*(-144) --42 + j*(10) -92 + j*(-43) --45 + j*(-206) --257 + j*(-30) --90 + j*(206) -115 + j*(66) --11 + j*(-71) --69 + j*(61) -85 + j*(42) --3 + j*(-151) --255 + j*(-30) --164 + j*(272) -136 + j*(253) -180 + j*(23) -35 + j*(-36) --21 + j*(70) -77 + j*(161) -246 + j*(105) -296 + j*(-127) -86 + j*(-293) --139 + j*(-175) --122 + j*(16) --23 + j*(62) -29 + j*(76) -148 + j*(69) -228 + j*(-103) -88 + j*(-265) --78 + j*(-213) --85 + j*(-136) --115 + j*(-165) --247 + j*(-107) --253 + j*(92) --76 + j*(185) -58 + j*(76) -3 + j*(-54) --125 + j*(-25) --125 + j*(115) -2 + j*(161) -76 + j*(91) -89 + j*(49) -140 + j*(-18) -88 + j*(-181) --148 + j*(-204) --255 + j*(20) --112 + j*(158) --23 + j*(98) --56 + j*(100) --4 + j*(156) -62 + j*(124) -68 + j*(116) -159 + j*(119) -223 + j*(-42) -63 + j*(-168) --75 + j*(-52) --2 + j*(51) -45 + j*(11) -22 + j*(23) -86 + j*(39) -112 + j*(-45) -52 + j*(-62) -90 + j*(-48) -91 + j*(-175) --97 + j*(-210) --167 + j*(-32) --47 + j*(19) --75 + j*(-48) --134 + j*(64) -28 + j*(141) -114 + j*(-26) --23 + j*(-104) --72 + j*(-25) --67 + j*(-39) --186 + j*(16) --132 + j*(243) -148 + j*(263) -255 + j*(40) -181 + j*(-93) -116 + j*(-193) --99 + j*(-260) --295 + j*(-11) --73 + j*(253) -186 + j*(70) -24 + j*(-122) --80 + j*(49) -122 + j*(68) -71 + j*(-155) --151 + j*(-36) -57 + j*(177) -284 + j*(-136) --108 + j*(-418) --460 + j*(-14) --102 + j*(373) -259 + j*(76) -0 + j*(-238) --278 + j*(4) --77 + j*(258) -132 + j*(125) -50 + j*(5) -30 + j*(89) -156 + j*(59) -136 + j*(-91) -25 + j*(-89) -60 + j*(-50) -67 + j*(-173) --136 + j*(-235) --296 + j*(-33) --186 + j*(202) -47 + j*(213) -152 + j*(32) -25 + j*(-130) --182 + j*(-38) --134 + j*(219) -156 + j*(234) -235 + j*(-38) -19 + j*(-140) --61 + j*(23) -84 + j*(67) -126 + j*(-87) --25 + j*(-165) --162 + j*(-55) --124 + j*(133) -90 + j*(179) -211 + j*(-38) -13 + j*(-212) --182 + j*(-48) --60 + j*(128) -51 + j*(36) --46 + j*(10) --1 + j*(147) -177 + j*(74) -106 + j*(-110) --42 + j*(-34) -55 + j*(71) -138 + j*(-32) -71 + j*(-79) -117 + j*(-62) -138 + j*(-248) --153 + j*(-356) --378 + j*(-59) --158 + j*(226) -103 + j*(93) -21 + j*(-108) --128 + j*(-50) --100 + j*(57) --52 + j*(62) --37 + j*(88) -56 + j*(103) -120 + j*(-14) -18 + j*(-119) --86 + j*(-52) --49 + j*(19) --28 + j*(-16) --78 + j*(4) --28 + j*(66) -40 + j*(-21) --94 + j*(-110) --235 + j*(46) --122 + j*(244) -82 + j*(224) -149 + j*(86) -103 + j*(-18) -2 + j*(-36) --35 + j*(56) -57 + j*(84) -52 + j*(-11) --54 + j*(59) -101 + j*(197) -290 + j*(-27) -21 + j*(-250) --200 + j*(57) -144 + j*(256) -317 + j*(-111) --35 + j*(-231) --62 + j*(93) -255 + j*(8) -97 + j*(-315) --196 + j*(-134) --5 + j*(62) -65 + j*(-169) --229 + j*(-138) --146 + j*(197) -177 + j*(89) -48 + j*(-173) --131 + j*(-8) -79 + j*(94) -136 + j*(-148) --89 + j*(-189) --98 + j*(-37) --33 + j*(-115) --235 + j*(-156) --340 + j*(135) --59 + j*(346) -229 + j*(163) -170 + j*(-139) --100 + j*(-177) --182 + j*(55) -35 + j*(134) -83 + j*(-104) --205 + j*(-132) --235 + j*(199) -92 + j*(236) -101 + j*(-49) --137 + j*(12) -4 + j*(226) -203 + j*(23) --34 + j*(-153) --190 + j*(95) -35 + j*(227) -117 + j*(71) -25 + j*(83) -146 + j*(158) -243 + j*(-14) -93 + j*(-117) -33 + j*(-8) -132 + j*(-5) -119 + j*(-95) -81 + j*(-100) -89 + j*(-154) --29 + j*(-220) --136 + j*(-104) --52 + j*(-29) --68 + j*(-131) --256 + j*(-42) --174 + j*(246) -167 + j*(237) -245 + j*(-77) -22 + j*(-215) --128 + j*(-107) --121 + j*(9) --64 + j*(64) -8 + j*(53) -4 + j*(-2) --37 + j*(31) -57 + j*(78) -134 + j*(-76) --64 + j*(-196) --221 + j*(20) --8 + j*(187) -134 + j*(-31) --113 + j*(-128) --178 + j*(175) -181 + j*(239) -266 + j*(-146) --107 + j*(-251) --209 + j*(91) -103 + j*(182) -199 + j*(-104) --37 + j*(-228) --179 + j*(-75) --117 + j*(39) --67 + j*(19) --123 + j*(6) --182 + j*(136) --29 + j*(314) -270 + j*(224) -297 + j*(-118) -5 + j*(-243) --147 + j*(-53) --59 + j*(62) --13 + j*(42) -6 + j*(65) -78 + j*(22) -16 + j*(-84) --120 + j*(-11) --54 + j*(141) -86 + j*(102) -69 + j*(6) -18 + j*(23) -39 + j*(59) -78 + j*(63) -129 + j*(35) -130 + j*(-42) -67 + j*(-43) -124 + j*(16) -233 + j*(-110) -101 + j*(-299) --107 + j*(-228) --93 + j*(-87) --44 + j*(-103) --73 + j*(-93) --12 + j*(-100) --74 + j*(-272) --402 + j*(-230) --477 + j*(182) --138 + j*(373) -49 + j*(196) --4 + j*(135) -72 + j*(177) -160 + j*(41) -48 + j*(-70) --42 + j*(-15) --48 + j*(32) --59 + j*(100) -64 + j*(181) -217 + j*(40) -97 + j*(-146) --69 + j*(-56) -16 + j*(49) -51 + j*(-58) --100 + j*(-43) --62 + j*(161) -190 + j*(142) -240 + j*(-128) -1 + j*(-267) --202 + j*(-106) --123 + j*(113) -81 + j*(69) -27 + j*(-138) --227 + j*(-65) --180 + j*(252) -156 + j*(284) -272 + j*(17) -142 + j*(-124) -55 + j*(-136) --46 + j*(-150) --151 + j*(-18) --26 + j*(148) -173 + j*(47) -125 + j*(-160) --49 + j*(-190) --146 + j*(-95) --146 + j*(23) --39 + j*(73) --4 + j*(-42) --192 + j*(-47) --214 + j*(250) -153 + j*(349) -335 + j*(-4) -52 + j*(-206) --117 + j*(13) -78 + j*(148) -223 + j*(-25) -107 + j*(-204) --91 + j*(-177) --137 + j*(24) -80 + j*(119) -240 + j*(-135) --16 + j*(-385) --337 + j*(-204) --276 + j*(81) --131 + j*(95) --144 + j*(98) --69 + j*(190) -58 + j*(122) -11 + j*(36) --13 + j*(97) -72 + j*(85) -51 + j*(5) -15 + j*(36) -71 + j*(20) -8 + j*(-52) --58 + j*(57) -110 + j*(100) -132 + j*(-136) --168 + j*(-152) --199 + j*(187) -130 + j*(242) -191 + j*(-30) --13 + j*(-49) -32 + j*(131) -248 + j*(64) -243 + j*(-201) --5 + j*(-322) --230 + j*(-169) --196 + j*(75) --16 + j*(98) --35 + j*(-2) --109 + j*(129) -127 + j*(247) -310 + j*(-20) -88 + j*(-214) --17 + j*(-38) -181 + j*(-79) -35 + j*(-376) --369 + j*(-230) --305 + j*(204) -51 + j*(236) -142 + j*(31) -117 + j*(-63) -76 + j*(-205) --181 + j*(-262) --340 + j*(21) --110 + j*(234) -94 + j*(80) --3 + j*(-83) --133 + j*(-50) --197 + j*(47) --180 + j*(219) -45 + j*(315) -223 + j*(128) -105 + j*(-37) -23 + j*(57) -156 + j*(66) -145 + j*(-112) --32 + j*(-117) --41 + j*(13) -35 + j*(-1) --9 + j*(-37) --20 + j*(28) -58 + j*(18) -37 + j*(-65) --47 + j*(-47) --27 + j*(33) -58 + j*(1) -15 + j*(-119) --175 + j*(-94) --216 + j*(169) -78 + j*(308) -295 + j*(36) -76 + j*(-201) --128 + j*(-14) -61 + j*(145) -202 + j*(-52) -37 + j*(-194) --88 + j*(-111) --111 + j*(-56) --168 + j*(45) --43 + j*(217) -190 + j*(112) -100 + j*(-115) --81 + j*(7) -115 + j*(171) -320 + j*(-76) -110 + j*(-345) --170 + j*(-251) --202 + j*(-48) --118 + j*(45) --31 + j*(53) -4 + j*(-3) --32 + j*(0) -56 + j*(38) -139 + j*(-158) --148 + j*(-346) --462 + j*(-49) --251 + j*(342) -106 + j*(250) -93 + j*(13) --2 + j*(1) --17 + j*(-29) --165 + j*(-13) --170 + j*(245) -145 + j*(297) -227 + j*(16) -27 + j*(-17) -124 + j*(132) -296 + j*(-95) -11 + j*(-325) --241 + j*(-57) --6 + j*(150) -126 + j*(-81) --124 + j*(-161) --195 + j*(89) -9 + j*(161) -58 + j*(30) --7 + j*(32) -46 + j*(65) -68 + j*(-27) --42 + j*(-48) --82 + j*(63) -6 + j*(127) -64 + j*(95) -73 + j*(83) -127 + j*(93) -195 + j*(22) -158 + j*(-81) -71 + j*(-58) -144 + j*(21) -292 + j*(-108) -192 + j*(-371) --107 + j*(-387) --221 + j*(-170) --129 + j*(-66) --102 + j*(-100) --140 + j*(-81) --131 + j*(-42) --135 + j*(-43) --150 + j*(-1) --105 + j*(19) --119 + j*(-37) --231 + j*(11) --203 + j*(185) --24 + j*(214) -26 + j*(82) --66 + j*(65) --45 + j*(161) -74 + j*(134) -50 + j*(-1) --112 + j*(23) --123 + j*(243) -134 + j*(355) -374 + j*(153) -311 + j*(-141) -69 + j*(-212) --59 + j*(-82) --23 + j*(46) -91 + j*(78) -191 + j*(-21) -141 + j*(-179) --24 + j*(-198) --78 + j*(-90) --41 + j*(-75) --111 + j*(-91) --164 + j*(45) --13 + j*(144) -105 + j*(21) -13 + j*(-90) --83 + j*(-31) --72 + j*(54) --16 + j*(114) -120 + j*(117) -209 + j*(-67) -25 + j*(-232) --168 + j*(-74) --19 + j*(94) -112 + j*(-90) --132 + j*(-218) --303 + j*(52) --74 + j*(267) -127 + j*(127) -59 + j*(10) -42 + j*(67) -127 + j*(27) -88 + j*(-70) -38 + j*(-35) -120 + j*(-59) -69 + j*(-244) --210 + j*(-252) --332 + j*(38) --124 + j*(254) -103 + j*(177) -129 + j*(16) -62 + j*(-56) --5 + j*(-55) --28 + j*(-5) -31 + j*(23) -71 + j*(-66) --43 + j*(-142) --154 + j*(-28) --56 + j*(91) -49 + j*(-14) --91 + j*(-120) --241 + j*(49) --97 + j*(265) -147 + j*(204) -175 + j*(4) -71 + j*(-74) -1 + j*(-69) --74 + j*(-44) --116 + j*(86) -41 + j*(211) -260 + j*(69) -173 + j*(-223) --151 + j*(-216) --218 + j*(95) -50 + j*(211) -184 + j*(-8) -11 + j*(-132) --96 + j*(4) -8 + j*(103) -95 + j*(48) -112 + j*(-3) -138 + j*(-74) -71 + j*(-193) --90 + j*(-191) --160 + j*(-76) --156 + j*(2) --149 + j*(106) -6 + j*(211) -207 + j*(63) -96 + j*(-185) --151 + j*(-116) --106 + j*(91) -28 + j*(43) --65 + j*(-14) --70 + j*(153) -167 + j*(157) -202 + j*(-108) --39 + j*(-171) --103 + j*(11) -18 + j*(47) -8 + j*(-15) --13 + j*(47) -106 + j*(54) -124 + j*(-97) --13 + j*(-128) --19 + j*(-32) -59 + j*(-93) --58 + j*(-210) --235 + j*(-93) --173 + j*(105) --12 + j*(91) --19 + j*(-16) --87 + j*(3) --59 + j*(40) --63 + j*(-13) --190 + j*(8) --238 + j*(218) --28 + j*(414) -288 + j*(330) -379 + j*(11) -155 + j*(-177) --21 + j*(-29) -142 + j*(110) -308 + j*(-112) -76 + j*(-364) --228 + j*(-204) --165 + j*(69) -11 + j*(55) --9 + j*(-9) -11 + j*(54) -137 + j*(-18) -57 + j*(-210) --174 + j*(-170) --202 + j*(40) --80 + j*(119) --4 + j*(99) -57 + j*(72) -91 + j*(-23) -2 + j*(-104) --105 + j*(-46) --95 + j*(64) --4 + j*(102) -67 + j*(42) -27 + j*(-38) --49 + j*(8) -37 + j*(84) -137 + j*(-60) --59 + j*(-211) --276 + j*(-4) --111 + j*(245) -100 + j*(150) -39 + j*(45) -44 + j*(131) -165 + j*(78) -103 + j*(-25) -91 + j*(86) -328 + j*(23) -293 + j*(-351) --117 + j*(-438) --303 + j*(-141) --199 + j*(38) --134 + j*(95) -3 + j*(163) -148 + j*(17) -15 + j*(-133) --74 + j*(6) -112 + j*(-8) -0 + j*(-288) --395 + j*(-139) --284 + j*(327) -161 + j*(292) -171 + j*(-38) --12 + j*(-35) -43 + j*(32) -42 + j*(-57) --28 + j*(-5) -96 + j*(-1) -39 + j*(-228) --286 + j*(-150) --209 + j*(217) -135 + j*(122) --25 + j*(-186) --325 + j*(42) --75 + j*(346) -185 + j*(126) --11 + j*(-35) --67 + j*(190) -208 + j*(199) -223 + j*(-86) --15 + j*(-120) --46 + j*(49) -71 + j*(74) -103 + j*(-5) -66 + j*(-67) --37 + j*(-75) --94 + j*(66) -62 + j*(173) -192 + j*(35) -88 + j*(-50) -105 + j*(66) -313 + j*(-35) -223 + j*(-352) --117 + j*(-362) --214 + j*(-116) --118 + j*(-18) --79 + j*(3) -4 + j*(16) -34 + j*(-110) --133 + j*(-130) --123 + j*(67) -101 + j*(-2) --35 + j*(-277) --377 + j*(-114) --243 + j*(260) -86 + j*(173) -13 + j*(-74) --164 + j*(1) --120 + j*(128) --76 + j*(166) -41 + j*(252) -271 + j*(109) -152 + j*(-218) --205 + j*(-132) --139 + j*(202) -138 + j*(141) -63 + j*(-48) --29 + j*(73) -163 + j*(103) -194 + j*(-156) --71 + j*(-252) --256 + j*(-65) --218 + j*(179) -21 + j*(313) -284 + j*(127) -158 + j*(-184) --140 + j*(-66) -32 + j*(200) -288 + j*(-52) --25 + j*(-322) --303 + j*(11) -8 + j*(266) -199 + j*(1) --21 + j*(-95) --13 + j*(100) -170 + j*(16) -52 + j*(-146) --64 + j*(-15) -80 + j*(44) -100 + j*(-100) --12 + j*(-95) -40 + j*(-29) -87 + j*(-139) --32 + j*(-217) --127 + j*(-185) --219 + j*(-163) --351 + j*(-13) --260 + j*(244) -8 + j*(251) -52 + j*(61) --82 + j*(55) --55 + j*(198) -103 + j*(207) -172 + j*(102) -163 + j*(34) -175 + j*(-6) -187 + j*(-92) -112 + j*(-191) --13 + j*(-187) --48 + j*(-117) --37 + j*(-129) --129 + j*(-146) --194 + j*(-21) --95 + j*(64) --56 + j*(-2) --133 + j*(26) --59 + j*(139) -74 + j*(41) --53 + j*(-100) --219 + j*(56) --78 + j*(266) -144 + j*(188) -136 + j*(12) -25 + j*(2) -35 + j*(95) -173 + j*(95) -249 + j*(-93) -69 + j*(-274) --174 + j*(-158) --117 + j*(83) -91 + j*(48) -60 + j*(-139) --109 + j*(-133) --146 + j*(-28) --153 + j*(18) --174 + j*(133) --21 + j*(262) -191 + j*(147) -131 + j*(-84) --91 + j*(-60) --91 + j*(168) -141 + j*(219) -254 + j*(37) -179 + j*(-83) -151 + j*(-97) -132 + j*(-204) --59 + j*(-262) --197 + j*(-70) --52 + j*(82) -57 + j*(-21) --24 + j*(-64) -4 + j*(2) -58 + j*(-95) --100 + j*(-137) --112 + j*(71) -148 + j*(45) -110 + j*(-274) --224 + j*(-282) --287 + j*(-44) --231 + j*(-8) --341 + j*(89) --217 + j*(372) -134 + j*(326) -149 + j*(50) -1 + j*(65) -110 + j*(130) -159 + j*(-41) --1 + j*(-98) --35 + j*(-6) --40 + j*(-34) --161 + j*(46) --49 + j*(272) -239 + j*(190) -215 + j*(-86) -18 + j*(-94) -22 + j*(13) -71 + j*(-9) -58 + j*(-19) -90 + j*(-33) -60 + j*(-100) --13 + j*(-57) -71 + j*(-2) -117 + j*(-132) --30 + j*(-194) --86 + j*(-75) --5 + j*(-81) -138 + j*(169) -171 + j*(-16) -31 + j*(-37) -76 + j*(78) -231 + j*(-36) -105 + j*(-274) --192 + j*(-209) --205 + j*(77) -11 + j*(123) -16 + j*(-23) --105 + j*(62) -64 + j*(218) -275 + j*(9) -74 + j*(-238) --168 + j*(-60) --8 + j*(139) -133 + j*(-11) --16 + j*(-84) --25 + j*(78) -161 + j*(52) -138 + j*(-136) --6 + j*(-127) -21 + j*(-45) -83 + j*(-111) -18 + j*(-208) --103 + j*(-223) --221 + j*(-151) --252 + j*(-1) --166 + j*(93) --98 + j*(93) --58 + j*(98) --4 + j*(57) --63 + j*(-6) --138 + j*(103) -16 + j*(211) -146 + j*(52) -10 + j*(-53) --27 + j*(73) -110 + j*(28) --1 + j*(-129) --175 + j*(21) --14 + j*(196) -130 + j*(52) -11 + j*(-21) -27 + j*(103) -193 + j*(16) -107 + j*(-202) --131 + j*(-188) --225 + j*(0) --151 + j*(190) -72 + j*(253) -236 + j*(65) -118 + j*(-120) -0 + j*(-57) -58 + j*(-48) --39 + j*(-142) --183 + j*(23) -5 + j*(203) -180 + j*(36) -63 + j*(-68) -97 + j*(18) -214 + j*(-175) --72 + j*(-381) --351 + j*(-119) --185 + j*(129) --79 + j*(41) --179 + j*(95) --40 + j*(252) -127 + j*(124) -24 + j*(40) -58 + j*(175) -269 + j*(78) -195 + j*(-171) -1 + j*(-156) --3 + j*(-79) --44 + j*(-112) --129 + j*(-7) --21 + j*(110) -84 + j*(32) -48 + j*(-4) -119 + j*(15) -174 + j*(-157) --36 + j*(-284) --210 + j*(-117) --117 + j*(38) --27 + j*(-5) --57 + j*(-45) --81 + j*(-31) --107 + j*(-19) --129 + j*(36) --92 + j*(88) --56 + j*(98) --28 + j*(129) -60 + j*(140) -129 + j*(58) -108 + j*(-37) -47 + j*(-77) --11 + j*(-66) --13 + j*(-17) -44 + j*(-52) --26 + j*(-168) --223 + j*(-115) --238 + j*(111) --64 + j*(192) -21 + j*(105) --16 + j*(61) --45 + j*(96) --6 + j*(173) -145 + j*(181) -225 + j*(-13) -28 + j*(-133) --81 + j*(72) -163 + j*(156) -250 + j*(-125) --13 + j*(-226) --88 + j*(-43) -2 + j*(-64) --158 + j*(-110) --231 + j*(163) -66 + j*(300) -243 + j*(77) -145 + j*(-66) -91 + j*(-82) --3 + j*(-118) --97 + j*(46) -150 + j*(188) -357 + j*(-127) -28 + j*(-403) --263 + j*(-116) --34 + j*(139) -162 + j*(-49) -13 + j*(-190) --71 + j*(-94) --10 + j*(-69) --17 + j*(-113) --30 + j*(-117) --39 + j*(-168) --137 + j*(-205) --234 + j*(-144) --278 + j*(-71) --324 + j*(36) --268 + j*(194) --107 + j*(233) --40 + j*(147) --77 + j*(115) --82 + j*(144) --68 + j*(184) -1 + j*(250) -151 + j*(223) -182 + j*(59) -47 + j*(4) -1 + j*(134) -144 + j*(217) -321 + j*(108) -336 + j*(-132) -124 + j*(-289) --108 + j*(-170) --71 + j*(62) -132 + j*(80) -207 + j*(-77) -137 + j*(-212) --21 + j*(-270) --189 + j*(-154) --143 + j*(55) -40 + j*(48) -29 + j*(-76) --23 + j*(-30) -86 + j*(-61) --16 + j*(-259) --301 + j*(-136) --191 + j*(176) -76 + j*(64) --82 + j*(-138) --248 + j*(69) --47 + j*(208) -20 + j*(65) --73 + j*(123) -99 + j*(208) -180 + j*(-16) --52 + j*(-37) -25 + j*(211) -308 + j*(54) -112 + j*(-242) --138 + j*(-21) -132 + j*(167) -282 + j*(-146) --18 + j*(-290) --132 + j*(-64) --1 + j*(-25) --52 + j*(-86) --66 + j*(31) -93 + j*(6) -41 + j*(-172) --129 + j*(-120) --83 + j*(-8) --58 + j*(-74) --164 + j*(-30) --86 + j*(102) -34 + j*(-6) --129 + j*(-104) --228 + j*(110) --2 + j*(228) -122 + j*(19) --69 + j*(-95) --194 + j*(75) --91 + j*(233) -55 + j*(252) -185 + j*(220) -327 + j*(85) -330 + j*(-186) -59 + j*(-378) --275 + j*(-226) --273 + j*(152) -69 + j*(266) -235 + j*(-11) -22 + j*(-172) --91 + j*(0) -83 + j*(44) -72 + j*(-172) --193 + j*(-160) --221 + j*(110) --21 + j*(165) --10 + j*(71) --45 + j*(179) -176 + j*(250) -351 + j*(4) -187 + j*(-248) --58 + j*(-215) --134 + j*(-49) --70 + j*(90) -96 + j*(116) -197 + j*(-52) -59 + j*(-202) --98 + j*(-122) --70 + j*(-14) --54 + j*(-15) --69 + j*(80) -129 + j*(153) -303 + j*(-96) -85 + j*(-378) --241 + j*(-274) --278 + j*(-6) --146 + j*(123) -7 + j*(137) -139 + j*(-3) -30 + j*(-230) --274 + j*(-177) --313 + j*(152) --42 + j*(278) -115 + j*(126) -76 + j*(6) -21 + j*(-25) --47 + j*(-20) --79 + j*(77) -37 + j*(151) -155 + j*(52) -115 + j*(-82) -19 + j*(-114) --53 + j*(-88) --88 + j*(-23) --47 + j*(28) --21 + j*(-10) --91 + j*(-20) --108 + j*(88) -8 + j*(125) -48 + j*(22) --56 + j*(-13) --115 + j*(101) --33 + j*(222) -136 + j*(245) -288 + j*(110) -260 + j*(-110) -67 + j*(-175) --20 + j*(-52) -64 + j*(-1) -83 + j*(-84) --3 + j*(-98) --11 + j*(-27) -53 + j*(-38) -29 + j*(-122) --88 + j*(-127) --158 + j*(-10) --103 + j*(127) -46 + j*(177) -194 + j*(92) -219 + j*(-91) -73 + j*(-203) --47 + j*(-112) -50 + j*(-37) -113 + j*(-226) --173 + j*(-369) --459 + j*(-75) --267 + j*(309) -103 + j*(266) -158 + j*(7) -39 + j*(-69) --4 + j*(-54) --42 + j*(-57) --64 + j*(-7) --15 + j*(-8) --68 + j*(-75) --190 + j*(26) --75 + j*(214) -159 + j*(127) -119 + j*(-120) --113 + j*(-125) --154 + j*(73) --1 + j*(133) -53 + j*(23) --35 + j*(-5) --37 + j*(91) -76 + j*(78) -54 + j*(-48) --77 + j*(-11) --22 + j*(120) -104 + j*(47) -5 + j*(-65) --92 + j*(55) -28 + j*(141) -81 + j*(59) -44 + j*(87) -179 + j*(117) -244 + j*(-84) -56 + j*(-171) -18 + j*(-42) -110 + j*(-112) --64 + j*(-203) --151 + j*(35) -129 + j*(78) -115 + j*(-264) --286 + j*(-228) --276 + j*(174) -35 + j*(175) --31 + j*(3) --115 + j*(204) -204 + j*(310) -392 + j*(-6) -218 + j*(-228) -87 + j*(-224) -16 + j*(-268) --153 + j*(-245) --214 + j*(-83) --144 + j*(-13) --146 + j*(-17) --177 + j*(42) --155 + j*(139) --41 + j*(238) -184 + j*(183) -202 + j*(-103) --98 + j*(-148) --96 + j*(172) -290 + j*(103) -187 + j*(-378) --361 + j*(-303) --335 + j*(233) -112 + j*(228) -70 + j*(-117) --220 + j*(-16) --105 + j*(269) -175 + j*(218) -240 + j*(-1) -139 + j*(-170) --76 + j*(-202) --206 + j*(-1) --41 + j*(163) -97 + j*(21) --49 + j*(-71) --110 + j*(96) -61 + j*(147) -104 + j*(8) -9 + j*(-8) -31 + j*(57) -87 + j*(23) -74 + j*(-18) -83 + j*(-41) -50 + j*(-121) --93 + j*(-125) --170 + j*(37) --49 + j*(194) -160 + j*(169) -248 + j*(-33) -101 + j*(-201) --77 + j*(-106) -16 + j*(42) -153 + j*(-100) --37 + j*(-273) --260 + j*(-90) --132 + j*(139) -43 + j*(68) --6 + j*(-21) --18 + j*(41) -70 + j*(1) --1 + j*(-109) --128 + j*(-21) --35 + j*(126) -136 + j*(49) -116 + j*(-148) --77 + j*(-223) --245 + j*(-94) --228 + j*(111) --66 + j*(186) -25 + j*(107) --4 + j*(63) --1 + j*(93) -39 + j*(82) -38 + j*(65) -63 + j*(76) -94 + j*(30) -45 + j*(6) -70 + j*(89) -226 + j*(30) -187 + j*(-206) --70 + j*(-217) --106 + j*(1) -54 + j*(12) -25 + j*(-103) --43 + j*(-42) -50 + j*(-44) --26 + j*(-195) --242 + j*(-65) --86 + j*(187) -168 + j*(5) --59 + j*(-237) --286 + j*(36) -18 + j*(249) -221 + j*(-82) --111 + j*(-298) --361 + j*(-28) --236 + j*(218) --90 + j*(258) -46 + j*(279) -197 + j*(146) -99 + j*(-45) --68 + j*(61) -70 + j*(210) -206 + j*(71) -90 + j*(-3) -121 + j*(132) -343 + j*(42) -306 + j*(-258) -44 + j*(-334) --93 + j*(-221) --117 + j*(-137) --129 + j*(-74) --117 + j*(-31) --138 + j*(6) --113 + j*(123) -61 + j*(161) -150 + j*(2) -51 + j*(-83) -28 + j*(-44) -50 + j*(-108) --72 + j*(-148) --126 + j*(-25) --35 + j*(-13) --116 + j*(-93) --243 + j*(79) --44 + j*(286) -213 + j*(133) -146 + j*(-103) --11 + j*(-98) --22 + j*(-30) --7 + j*(-33) --11 + j*(-42) --28 + j*(-73) --112 + j*(-69) --141 + j*(33) --66 + j*(71) --74 + j*(28) --130 + j*(108) --23 + j*(220) -121 + j*(146) -100 + j*(47) -80 + j*(74) -177 + j*(49) -192 + j*(-122) -4 + j*(-225) --177 + j*(-88) --115 + j*(122) -74 + j*(116) -81 + j*(-32) --33 + j*(-11) -33 + j*(89) -124 + j*(-4) -15 + j*(-59) -33 + j*(91) -272 + j*(5) -190 + j*(-344) --204 + j*(-337) --279 + j*(-7) --79 + j*(77) --61 + j*(-11) --98 + j*(45) --18 + j*(73) --5 + j*(12) --30 + j*(23) --7 + j*(-3) --117 + j*(-27) --175 + j*(190) -113 + j*(332) -339 + j*(58) -153 + j*(-180) --6 + j*(-69) -95 + j*(-9) -112 + j*(-137) -5 + j*(-180) --50 + j*(-175) --165 + j*(-189) --298 + j*(-45) --235 + j*(155) --98 + j*(201) --30 + j*(216) -103 + j*(233) -236 + j*(89) -165 + j*(-84) -43 + j*(-76) -48 + j*(-39) -39 + j*(-93) --65 + j*(-92) --103 + j*(33) -16 + j*(115) -131 + j*(11) -40 + j*(-123) --109 + j*(-20) -25 + j*(151) -238 + j*(-4) -93 + j*(-249) --129 + j*(-137) --25 + j*(4) -26 + j*(-148) --188 + j*(-151) --175 + j*(78) -18 + j*(22) --127 + j*(-142) --316 + j*(84) --95 + j*(322) -147 + j*(190) -126 + j*(31) -100 + j*(-28) -6 + j*(-132) --205 + j*(-31) --122 + j*(247) -168 + j*(197) -136 + j*(-45) --29 + j*(11) -76 + j*(120) -163 + j*(-8) -53 + j*(-73) -34 + j*(-1) -80 + j*(-33) -23 + j*(-58) -38 + j*(-1) -97 + j*(-74) --21 + j*(-153) --113 + j*(-23) --6 + j*(59) -35 + j*(-18) --14 + j*(3) -79 + j*(45) -146 + j*(-105) --11 + j*(-223) --163 + j*(-120) --147 + j*(15) --73 + j*(63) --5 + j*(44) --18 + j*(-26) --122 + j*(21) --46 + j*(200) -216 + j*(142) -220 + j*(-159) --49 + j*(-223) --127 + j*(-42) --32 + j*(-11) --76 + j*(-63) --124 + j*(33) --28 + j*(82) --2 + j*(9) --49 + j*(31) -21 + j*(60) -26 + j*(-55) --136 + j*(-30) --95 + j*(194) -192 + j*(163) -202 + j*(-169) --139 + j*(-247) --292 + j*(45) --106 + j*(243) -64 + j*(181) -78 + j*(105) -98 + j*(102) -156 + j*(51) -143 + j*(-47) -60 + j*(-82) -14 + j*(-37) -42 + j*(-9) -54 + j*(-51) --11 + j*(-55) --8 + j*(37) -132 + j*(31) -141 + j*(-167) --99 + j*(-227) --214 + j*(21) -16 + j*(170) -176 + j*(-35) -1 + j*(-192) --143 + j*(-53) --38 + j*(50) -16 + j*(-36) --76 + j*(-49) --75 + j*(47) -4 + j*(50) -15 + j*(9) -35 + j*(7) -62 + j*(-85) --89 + j*(-181) --284 + j*(-24) --200 + j*(250) -75 + j*(296) -235 + j*(119) -209 + j*(-78) -54 + j*(-180) --109 + j*(-104) --86 + j*(60) -50 + j*(40) --7 + j*(-86) --163 + j*(18) --50 + j*(236) -219 + j*(178) -261 + j*(-81) -93 + j*(-204) --46 + j*(-151) --62 + j*(-53) -9 + j*(-37) --6 + j*(-150) --204 + j*(-142) --251 + j*(129) -44 + j*(235) -179 + j*(-49) --92 + j*(-185) --224 + j*(63) --23 + j*(180) -44 + j*(37) --61 + j*(49) -11 + j*(160) -138 + j*(74) -73 + j*(-49) --30 + j*(-4) --8 + j*(94) -106 + j*(132) -247 + j*(18) -187 + j*(-228) --112 + j*(-264) --233 + j*(19) --22 + j*(182) -129 + j*(60) -98 + j*(-37) -78 + j*(-68) -28 + j*(-122) --53 + j*(-83) --20 + j*(-33) --34 + j*(-88) --128 + j*(-16) --5 + j*(105) -121 + j*(-70) --107 + j*(-190) --213 + j*(73) -61 + j*(124) -12 + j*(-165) --330 + j*(-8) --106 + j*(413) -366 + j*(186) -166 + j*(-272) --235 + j*(-93) --61 + j*(252) -247 + j*(101) -165 + j*(-173) --52 + j*(-185) --144 + j*(-51) --87 + j*(78) -44 + j*(53) --8 + j*(-77) --158 + j*(33) --1 + j*(223) -214 + j*(47) -35 + j*(-146) --105 + j*(49) -132 + j*(135) -194 + j*(-134) --62 + j*(-203) --132 + j*(-12) --42 + j*(33) --53 + j*(45) -37 + j*(127) -180 + j*(4) -67 + j*(-156) --43 + j*(-66) -58 + j*(-57) --21 + j*(-222) --253 + j*(-117) --170 + j*(121) -4 + j*(33) --148 + j*(-78) --264 + j*(141) --60 + j*(298) -76 + j*(199) -69 + j*(198) -254 + j*(226) -409 + j*(-74) -118 + j*(-368) --250 + j*(-156) --117 + j*(216) -229 + j*(144) -211 + j*(-153) -4 + j*(-170) -17 + j*(-78) -25 + j*(-194) --210 + j*(-213) --315 + j*(76) --71 + j*(266) -132 + j*(136) -108 + j*(-1) -71 + j*(-26) -48 + j*(-62) --4 + j*(-49) -31 + j*(-17) -52 + j*(-103) --76 + j*(-139) --118 + j*(-13) --18 + j*(-8) --95 + j*(-107) --242 + j*(40) --76 + j*(244) -146 + j*(102) -25 + j*(-105) --175 + j*(8) --96 + j*(219) -109 + j*(235) -243 + j*(102) -238 + j*(-103) -35 + j*(-230) --175 + j*(-71) --66 + j*(175) -197 + j*(110) -174 + j*(-141) --46 + j*(-141) --14 + j*(55) -214 + j*(-29) -127 + j*(-362) --308 + j*(-368) --463 + j*(72) --127 + j*(339) -137 + j*(142) -37 + j*(-33) --33 + j*(45) -71 + j*(40) -31 + j*(-100) --148 + j*(-56) --133 + j*(151) -80 + j*(188) -175 + j*(-13) --8 + j*(-161) --218 + j*(16) --62 + j*(306) -307 + j*(204) -282 + j*(-192) --77 + j*(-222) --102 + j*(70) -148 + j*(46) -76 + j*(-195) --163 + j*(-113) --102 + j*(98) -49 + j*(60) -26 + j*(-11) -32 + j*(3) -41 + j*(-80) --122 + j*(-91) --158 + j*(142) -111 + j*(235) -263 + j*(-9) -100 + j*(-180) --24 + j*(-112) --10 + j*(-76) --56 + j*(-92) --91 + j*(-4) -8 + j*(40) -39 + j*(-65) --73 + j*(-80) --68 + j*(33) -44 + j*(-6) --33 + j*(-130) --175 + j*(-30) --64 + j*(118) -66 + j*(-15) --110 + j*(-141) --264 + j*(64) --81 + j*(255) -96 + j*(142) -45 + j*(30) -16 + j*(57) -28 + j*(26) --52 + j*(40) --20 + j*(188) -189 + j*(180) -245 + j*(-30) -107 + j*(-127) -26 + j*(-82) -10 + j*(-51) -16 + j*(-8) -87 + j*(-27) -52 + j*(-146) --113 + j*(-113) --96 + j*(65) -66 + j*(48) -40 + j*(-81) --51 + j*(-44) --7 + j*(-4) --27 + j*(-67) --122 + j*(-4) --56 + j*(119) -57 + j*(86) -60 + j*(37) -102 + j*(34) -138 + j*(-71) -28 + j*(-156) --66 + j*(-100) --81 + j*(-52) --119 + j*(24) --2 + j*(164) -234 + j*(32) -120 + j*(-280) --211 + j*(-208) --163 + j*(80) -48 + j*(6) --82 + j*(-158) --237 + j*(8) --83 + j*(151) -16 + j*(23) --105 + j*(-33) --162 + j*(88) --88 + j*(173) --7 + j*(180) -49 + j*(146) -41 + j*(116) -52 + j*(172) -192 + j*(187) -280 + j*(25) -190 + j*(-87) -165 + j*(-76) -192 + j*(-189) -2 + j*(-319) --212 + j*(-167) --150 + j*(40) --28 + j*(29) --51 + j*(-14) --64 + j*(33) --37 + j*(63) --5 + j*(105) -121 + j*(116) -203 + j*(-59) -33 + j*(-202) --124 + j*(-63) --6 + j*(66) -93 + j*(-57) --46 + j*(-152) --161 + j*(-16) --57 + j*(126) -104 + j*(80) -132 + j*(-82) -4 + j*(-183) --140 + j*(-127) --165 + j*(3) --103 + j*(65) --59 + j*(71) --27 + j*(72) --1 + j*(49) --18 + j*(29) --30 + j*(56) --1 + j*(76) -23 + j*(69) -44 + j*(73) -88 + j*(52) -102 + j*(-11) -66 + j*(-52) -34 + j*(-64) --6 + j*(-72) --51 + j*(-47) --64 + j*(-3) --70 + j*(43) --40 + j*(127) -103 + j*(165) -236 + j*(36) -203 + j*(-141) -91 + j*(-225) --43 + j*(-272) --245 + j*(-207) --314 + j*(58) --100 + j*(226) -71 + j*(105) -6 + j*(12) -8 + j*(86) -137 + j*(24) -72 + j*(-169) --155 + j*(-161) --243 + j*(38) --152 + j*(206) -35 + j*(274) -239 + j*(147) -209 + j*(-130) --77 + j*(-184) --187 + j*(78) -30 + j*(220) -177 + j*(68) -86 + j*(-40) -37 + j*(33) -138 + j*(57) -199 + j*(-63) -119 + j*(-182) --6 + j*(-187) --65 + j*(-117) --58 + j*(-79) --84 + j*(-76) --130 + j*(1) --47 + j*(105) -95 + j*(50) -74 + j*(-98) --52 + j*(-102) --61 + j*(-11) -1 + j*(-19) --22 + j*(-62) --42 + j*(-39) --13 + j*(-65) --95 + j*(-143) --254 + j*(-52) --218 + j*(170) --1 + j*(207) -68 + j*(42) --62 + j*(-22) --127 + j*(99) --28 + j*(198) -100 + j*(168) -161 + j*(67) -137 + j*(-53) -23 + j*(-115) --88 + j*(-56) --102 + j*(47) --71 + j*(115) --13 + j*(189) -136 + j*(218) -274 + j*(76) -213 + j*(-101) -94 + j*(-103) -122 + j*(-74) -119 + j*(-194) --63 + j*(-236) --153 + j*(-74) --51 + j*(-9) --75 + j*(-94) --219 + j*(11) --104 + j*(242) -171 + j*(182) -173 + j*(-53) -30 + j*(-60) -84 + j*(1) -123 + j*(-148) --86 + j*(-216) --199 + j*(-1) --18 + j*(121) -79 + j*(-26) --52 + j*(-82) --74 + j*(56) -83 + j*(62) -101 + j*(-119) --90 + j*(-180) --211 + j*(-8) --95 + j*(165) -104 + j*(121) -125 + j*(-66) --21 + j*(-136) --109 + j*(-46) --74 + j*(21) --54 + j*(21) --50 + j*(49) -8 + j*(59) -33 + j*(-11) --33 + j*(-55) --105 + j*(-14) --122 + j*(79) --34 + j*(183) -147 + j*(138) -163 + j*(-91) --69 + j*(-154) --146 + j*(50) -21 + j*(95) --13 + j*(-51) --182 + j*(74) --1 + j*(296) -258 + j*(112) -97 + j*(-134) --93 + j*(26) -86 + j*(161) -185 + j*(-30) -3 + j*(-100) --35 + j*(62) -97 + j*(78) -108 + j*(9) -132 + j*(20) -209 + j*(-88) -66 + j*(-243) --126 + j*(-114) --15 + j*(74) -154 + j*(-27) -83 + j*(-182) --23 + j*(-168) --54 + j*(-163) --157 + j*(-145) --198 + j*(7) --65 + j*(86) --8 + j*(4) --59 + j*(11) -16 + j*(64) -93 + j*(-59) --44 + j*(-173) --175 + j*(-67) --128 + j*(35) --103 + j*(34) --101 + j*(98) -22 + j*(112) -37 + j*(-44) --161 + j*(-40) --138 + j*(218) -171 + j*(208) -193 + j*(-130) --136 + j*(-187) --226 + j*(96) --24 + j*(198) -43 + j*(97) -25 + j*(105) -112 + j*(83) -74 + j*(-59) --106 + j*(-1) --40 + j*(228) -238 + j*(198) -291 + j*(-81) -85 + j*(-223) --102 + j*(-134) --134 + j*(42) --7 + j*(164) -153 + j*(119) -189 + j*(-5) -176 + j*(-74) -160 + j*(-194) --38 + j*(-299) --253 + j*(-97) --90 + j*(166) -163 + j*(25) -18 + j*(-195) --168 + j*(-37) -6 + j*(115) -129 + j*(-74) --57 + j*(-192) --192 + j*(-52) --152 + j*(83) --61 + j*(173) -138 + j*(174) -239 + j*(-86) --32 + j*(-259) --235 + j*(6) -30 + j*(211) -244 + j*(-52) -16 + j*(-287) --218 + j*(-146) --188 + j*(21) --148 + j*(50) --149 + j*(127) --40 + j*(220) -122 + j*(177) -188 + j*(19) -91 + j*(-129) --91 + j*(-100) --105 + j*(88) -85 + j*(121) -137 + j*(-74) --48 + j*(-150) --143 + j*(8) --28 + j*(99) -43 + j*(16) --33 + j*(-38) --91 + j*(52) -11 + j*(128) -108 + j*(16) --25 + j*(-107) --197 + j*(54) --35 + j*(287) -231 + j*(175) -180 + j*(-54) -37 + j*(-19) -104 + j*(53) -146 + j*(-32) -103 + j*(-37) -197 + j*(-47) -201 + j*(-274) --88 + j*(-373) --273 + j*(-151) --202 + j*(18) --151 + j*(68) --64 + j*(161) -115 + j*(89) -55 + j*(-106) --114 + j*(-28) -2 + j*(107) -102 + j*(-45) --75 + j*(-107) --86 + j*(72) -73 + j*(25) --35 + j*(-103) --129 + j*(71) -110 + j*(129) -143 + j*(-177) --216 + j*(-223) --318 + j*(144) --21 + j*(317) -190 + j*(157) -169 + j*(-28) -50 + j*(-92) --35 + j*(-16) -55 + j*(55) -124 + j*(-91) --76 + j*(-184) --195 + j*(43) -23 + j*(168) -127 + j*(-21) --24 + j*(-86) --48 + j*(16) --13 + j*(1) --77 + j*(50) -61 + j*(185) -277 + j*(-13) -76 + j*(-301) --230 + j*(-147) --134 + j*(109) -17 + j*(51) --36 + j*(18) -34 + j*(83) -119 + j*(-69) --88 + j*(-181) --231 + j*(35) --56 + j*(187) -56 + j*(81) -0 + j*(47) -33 + j*(84) -54 + j*(20) --30 + j*(49) -67 + j*(183) -291 + j*(59) -209 + j*(-247) --123 + j*(-255) --218 + j*(47) -18 + j*(204) -210 + j*(45) -127 + j*(-150) --28 + j*(-127) --19 + j*(-28) -41 + j*(-64) --23 + j*(-112) --67 + j*(-49) --11 + j*(-40) --58 + j*(-117) --178 + j*(-32) --90 + j*(123) -77 + j*(41) --18 + j*(-128) --199 + j*(-32) --130 + j*(159) -25 + j*(129) -2 + j*(50) --11 + j*(135) -169 + j*(147) -255 + j*(-99) -20 + j*(-288) --238 + j*(-140) --201 + j*(104) --42 + j*(139) --18 + j*(82) --24 + j*(129) -86 + j*(163) -189 + j*(54) -141 + j*(-90) -16 + j*(-121) --60 + j*(-47) --37 + j*(35) -34 + j*(42) -54 + j*(-21) -1 + j*(-56) --64 + j*(-23) --86 + j*(66) --4 + j*(176) -185 + j*(168) -293 + j*(-25) -189 + j*(-211) -37 + j*(-234) --41 + j*(-211) --153 + j*(-193) --257 + j*(-36) --156 + j*(163) -59 + j*(153) -124 + j*(-12) -31 + j*(-100) --38 + j*(-74) --36 + j*(-50) --52 + j*(-71) --115 + j*(-49) --112 + j*(33) --35 + j*(22) --97 + j*(-69) --265 + j*(47) --158 + j*(327) -183 + j*(303) -255 + j*(-6) -49 + j*(-117) --35 + j*(-29) --37 + j*(-11) --100 + j*(52) --19 + j*(184) -144 + j*(127) -116 + j*(0) -74 + j*(40) -171 + j*(14) -134 + j*(-144) --31 + j*(-127) --19 + j*(-9) -37 + j*(-53) --46 + j*(-69) --46 + j*(33) -40 + j*(25) -20 + j*(-9) -61 + j*(40) -169 + j*(-71) -25 + j*(-241) --170 + j*(-106) --41 + j*(49) -47 + j*(-108) --164 + j*(-161) --221 + j*(74) --23 + j*(134) -0 + j*(1) --84 + j*(45) -12 + j*(110) -64 + j*(-10) --69 + j*(-43) --93 + j*(108) -71 + j*(156) -163 + j*(8) -57 + j*(-125) --102 + j*(-61) --56 + j*(121) -161 + j*(79) -127 + j*(-186) --178 + j*(-166) --173 + j*(155) -146 + j*(148) -126 + j*(-161) --166 + j*(-127) --125 + j*(134) -91 + j*(84) -23 + j*(-89) --124 + j*(-6) --51 + j*(129) -67 + j*(97) -84 + j*(18) -59 + j*(-33) -6 + j*(-53) --37 + j*(-18) --30 + j*(18) --25 + j*(32) --8 + j*(62) -33 + j*(58) -24 + j*(46) -67 + j*(115) -241 + j*(51) -215 + j*(-228) --107 + j*(-264) --177 + j*(41) -102 + j*(90) -109 + j*(-188) --174 + j*(-182) --178 + j*(73) -10 + j*(71) --40 + j*(-48) --136 + j*(58) --13 + j*(171) -109 + j*(90) -91 + j*(7) -77 + j*(-2) -96 + j*(-32) -83 + j*(-88) -29 + j*(-134) --59 + j*(-119) --66 + j*(-29) -28 + j*(-53) --49 + j*(-205) --292 + j*(-125) --271 + j*(165) --31 + j*(194) --34 + j*(57) --119 + j*(175) -101 + j*(296) -293 + j*(71) -163 + j*(-140) -30 + j*(-122) --22 + j*(-136) --182 + j*(-74) --144 + j*(190) -173 + j*(177) -170 + j*(-153) --148 + j*(-142) --109 + j*(144) -128 + j*(57) --21 + j*(-135) --193 + j*(74) -42 + j*(246) -203 + j*(37) -45 + j*(-69) -21 + j*(54) -144 + j*(16) -93 + j*(-97) -38 + j*(-51) -118 + j*(-80) -45 + j*(-235) --166 + j*(-204) --220 + j*(-24) --149 + j*(75) --78 + j*(117) -16 + j*(105) -23 + j*(11) --76 + j*(37) --7 + j*(185) -194 + j*(125) -190 + j*(-84) -45 + j*(-119) -28 + j*(-83) --14 + j*(-139) --162 + j*(-71) --115 + j*(148) -133 + j*(147) -187 + j*(-83) -16 + j*(-179) --76 + j*(-82) --33 + j*(-36) --30 + j*(-78) --91 + j*(-79) --127 + j*(-24) --125 + j*(30) --112 + j*(84) --52 + j*(161) -103 + j*(162) -213 + j*(-22) -71 + j*(-232) --186 + j*(-186) --230 + j*(35) --110 + j*(97) --126 + j*(50) --202 + j*(181) --38 + j*(369) -234 + j*(290) -279 + j*(59) -192 + j*(-30) -180 + j*(-76) -80 + j*(-197) --156 + j*(-118) --127 + j*(197) -230 + j*(240) -357 + j*(-110) -89 + j*(-301) --90 + j*(-158) --49 + j*(-65) --64 + j*(-64) --56 + j*(29) -84 + j*(9) -41 + j*(-170) --170 + j*(-97) --65 + j*(140) -202 + j*(-10) -26 + j*(-335) --357 + j*(-192) --310 + j*(196) --2 + j*(245) -78 + j*(64) -8 + j*(8) --12 + j*(19) --44 + j*(29) --33 + j*(104) -85 + j*(107) -105 + j*(-25) --24 + j*(-45) --27 + j*(93) -144 + j*(96) -188 + j*(-94) -28 + j*(-198) --100 + j*(-114) --93 + j*(-23) --74 + j*(-4) --90 + j*(39) --28 + j*(117) -111 + j*(85) -137 + j*(-92) --47 + j*(-187) --205 + j*(-25) --78 + j*(178) -155 + j*(92) -112 + j*(-166) --160 + j*(-181) --235 + j*(68) --44 + j*(175) -44 + j*(33) --103 + j*(-21) --174 + j*(165) -8 + j*(320) -242 + j*(232) -292 + j*(9) -166 + j*(-132) -25 + j*(-111) --6 + j*(-17) -49 + j*(25) -98 + j*(0) -110 + j*(-52) -78 + j*(-95) -43 + j*(-95) -57 + j*(-105) -17 + j*(-192) --161 + j*(-177) --211 + j*(55) -24 + j*(159) -147 + j*(-49) --27 + j*(-159) --86 + j*(-21) -30 + j*(-39) --74 + j*(-160) --217 + j*(10) -6 + j*(170) -178 + j*(-110) --146 + j*(-326) --436 + j*(-13) --206 + j*(317) -84 + j*(190) --2 + j*(-10) --135 + j*(107) -26 + j*(238) -175 + j*(51) --33 + j*(-112) --230 + j*(151) -72 + j*(428) -441 + j*(163) -285 + j*(-211) -31 + j*(-141) -122 + j*(-71) -59 + j*(-276) --257 + j*(-174) --159 + j*(170) -137 + j*(47) --65 + j*(-188) --270 + j*(93) -35 + j*(292) -190 + j*(24) --17 + j*(-28) -60 + j*(139) -204 + j*(-42) --46 + j*(-151) --100 + j*(155) -249 + j*(170) -259 + j*(-165) -19 + j*(-155) -119 + j*(-50) -136 + j*(-286) --193 + j*(-291) --197 + j*(45) -93 + j*(-6) --42 + j*(-261) --276 + j*(-72) --58 + j*(115) -63 + j*(-158) --290 + j*(-265) --474 + j*(115) --182 + j*(390) -96 + j*(258) -81 + j*(59) --41 + j*(51) --43 + j*(172) -125 + j*(212) -248 + j*(37) -133 + j*(-148) --28 + j*(-124) --58 + j*(-66) --134 + j*(-73) --265 + j*(95) --115 + j*(383) -272 + j*(359) -402 + j*(-1) -164 + j*(-211) --20 + j*(-98) -35 + j*(7) -76 + j*(-46) -15 + j*(-50) -42 + j*(10) -103 + j*(-47) -29 + j*(-105) -1 + j*(-14) -133 + j*(-28) -109 + j*(-211) --85 + j*(-211) --73 + j*(-80) --12 + j*(-185) --257 + j*(-252) --415 + j*(74) --114 + j*(316) -127 + j*(92) --46 + j*(-83) --161 + j*(90) -21 + j*(185) -119 + j*(18) --19 + j*(-86) --134 + j*(21) --71 + j*(149) -52 + j*(132) -54 + j*(53) -23 + j*(91) -148 + j*(122) -232 + j*(-80) -6 + j*(-236) --189 + j*(-35) --30 + j*(151) -110 + j*(29) -18 + j*(-44) -18 + j*(25) -71 + j*(-54) --92 + j*(-98) --150 + j*(140) -132 + j*(248) -313 + j*(-16) -139 + j*(-256) --113 + j*(-218) --223 + j*(-1) --79 + j*(244) -271 + j*(206) -365 + j*(-177) -55 + j*(-370) --127 + j*(-204) --74 + j*(-156) --203 + j*(-210) --339 + j*(19) --121 + j*(228) -83 + j*(73) --7 + j*(-76) --74 + j*(-42) --105 + j*(-87) --296 + j*(-25) --277 + j*(303) -100 + j*(375) -226 + j*(42) --40 + j*(-61) --86 + j*(187) -175 + j*(223) -258 + j*(-19) -107 + j*(-147) --11 + j*(-129) --97 + j*(-93) --180 + j*(18) --139 + j*(190) -23 + j*(274) -184 + j*(236) -315 + j*(129) -383 + j*(-73) -267 + j*(-321) --45 + j*(-396) --294 + j*(-148) --168 + j*(194) -203 + j*(185) -301 + j*(-173) --1 + j*(-367) --240 + j*(-165) --136 + j*(38) -1 + j*(-26) --81 + j*(-139) --235 + j*(-66) --253 + j*(145) --54 + j*(307) -235 + j*(204) -265 + j*(-140) --65 + j*(-286) --284 + j*(-6) --80 + j*(246) -168 + j*(127) -129 + j*(-69) -18 + j*(-79) -10 + j*(-55) --6 + j*(-84) --62 + j*(-88) --127 + j*(-64) --195 + j*(52) --80 + j*(241) -212 + j*(180) -235 + j*(-160) --88 + j*(-255) --211 + j*(1) --27 + j*(86) --21 + j*(-64) --187 + j*(-4) --112 + j*(192) -86 + j*(136) -46 + j*(-40) --119 + j*(-14) --132 + j*(142) --19 + j*(224) -86 + j*(201) -132 + j*(159) -184 + j*(144) -286 + j*(71) -287 + j*(-121) -101 + j*(-206) -8 + j*(-66) -159 + j*(-26) -183 + j*(-241) --70 + j*(-322) --205 + j*(-115) --80 + j*(1) --47 + j*(-96) --193 + j*(-70) --182 + j*(145) -61 + j*(205) -191 + j*(-12) -30 + j*(-181) --134 + j*(-75) --66 + j*(42) --21 + j*(-38) --177 + j*(-21) --162 + j*(250) -190 + j*(324) -389 + j*(-1) -202 + j*(-268) --9 + j*(-250) --85 + j*(-190) --165 + j*(-132) --175 + j*(-1) --69 + j*(38) --55 + j*(-35) --124 + j*(-18) --110 + j*(44) --94 + j*(37) --130 + j*(83) --62 + j*(179) -81 + j*(139) -98 + j*(-9) --30 + j*(-78) --156 + j*(11) --132 + j*(190) -69 + j*(250) -196 + j*(72) -58 + j*(-65) --54 + j*(53) -72 + j*(150) -165 + j*(21) -50 + j*(-70) --45 + j*(34) -35 + j*(168) -235 + j*(170) -391 + j*(-54) -242 + j*(-366) --132 + j*(-349) --209 + j*(-13) -61 + j*(66) -103 + j*(-178) --140 + j*(-204) --170 + j*(10) --18 + j*(20) --69 + j*(-89) --191 + j*(18) --77 + j*(186) -122 + j*(123) -134 + j*(-72) --21 + j*(-153) --157 + j*(-62) --147 + j*(90) --30 + j*(162) -78 + j*(128) -128 + j*(52) -129 + j*(-39) -54 + j*(-112) --57 + j*(-70) --37 + j*(69) -148 + j*(86) -257 + j*(-141) -59 + j*(-385) --279 + j*(-310) --349 + j*(4) --136 + j*(132) --54 + j*(-13) --226 + j*(-44) --296 + j*(187) --86 + j*(364) -149 + j*(270) -174 + j*(87) -90 + j*(40) -105 + j*(76) -181 + j*(-5) -86 + j*(-147) --91 + j*(-65) --9 + j*(110) -159 + j*(-8) --11 + j*(-176) --190 + j*(42) -68 + j*(233) -261 + j*(-37) -21 + j*(-206) --69 + j*(-16) -96 + j*(-71) --120 + j*(-277) --433 + j*(43) --113 + j*(453) -306 + j*(214) -134 + j*(-105) --35 + j*(83) -228 + j*(158) -294 + j*(-152) -21 + j*(-230) --8 + j*(-52) -100 + j*(-127) --74 + j*(-223) --178 + j*(4) -83 + j*(98) -169 + j*(-205) --161 + j*(-320) --317 + j*(-17) --81 + j*(132) -8 + j*(-56) --179 + j*(-90) --199 + j*(103) --43 + j*(113) --83 + j*(4) --197 + j*(112) --80 + j*(269) -73 + j*(223) -95 + j*(174) -190 + j*(176) -292 + j*(6) -148 + j*(-172) --16 + j*(-81) -67 + j*(17) -118 + j*(-107) --34 + j*(-157) --94 + j*(-16) -16 + j*(43) -71 + j*(-37) -34 + j*(-95) --16 + j*(-122) --96 + j*(-127) --170 + j*(-51) --168 + j*(58) --98 + j*(134) -1 + j*(136) -44 + j*(64) --2 + j*(47) -29 + j*(110) -141 + j*(53) -81 + j*(-95) --76 + j*(-31) -3 + j*(137) -197 + j*(63) -176 + j*(-136) -30 + j*(-194) --62 + j*(-160) --128 + j*(-101) --132 + j*(-6) --75 + j*(22) --81 + j*(8) --88 + j*(57) --30 + j*(64) --62 + j*(31) --95 + j*(136) -72 + j*(214) -193 + j*(50) -74 + j*(-64) -23 + j*(25) -122 + j*(24) -123 + j*(-87) -58 + j*(-127) -1 + j*(-174) --169 + j*(-155) --218 + j*(85) -28 + j*(179) -113 + j*(-44) --93 + j*(-81) --86 + j*(119) -101 + j*(91) -65 + j*(-50) -4 + j*(-4) -80 + j*(-27) --8 + j*(-143) --153 + j*(-26) --38 + j*(117) -76 + j*(17) --6 + j*(-52) --33 + j*(6) --18 + j*(-1) --59 + j*(51) -66 + j*(141) -221 + j*(-31) -57 + j*(-251) --185 + j*(-149) --173 + j*(52) --64 + j*(115) -47 + j*(105) -112 + j*(-37) --73 + j*(-145) --216 + j*(90) -59 + j*(261) -247 + j*(-18) --3 + j*(-190) --117 + j*(4) -4 + j*(30) --83 + j*(-12) --57 + j*(210) -305 + j*(148) -264 + j*(-318) --233 + j*(-344) --327 + j*(86) --46 + j*(213) -59 + j*(112) -123 + j*(61) -132 + j*(-136) --174 + j*(-194) --283 + j*(185) -114 + j*(347) -311 + j*(16) -122 + j*(-151) -63 + j*(-121) --25 + j*(-228) --282 + j*(-91) --136 + j*(250) -212 + j*(86) --5 + j*(-243) --327 + j*(39) --32 + j*(371) -282 + j*(131) -129 + j*(-94) -45 + j*(4) -151 + j*(-32) -63 + j*(-173) --78 + j*(-105) --53 + j*(-16) --42 + j*(-6) --19 + j*(64) -116 + j*(46) -123 + j*(-122) --24 + j*(-168) --87 + j*(-91) --96 + j*(-54) --105 + j*(11) --15 + j*(45) -6 + j*(-69) --151 + j*(-69) --148 + j*(140) -89 + j*(154) -129 + j*(-83) --83 + j*(-156) --197 + j*(5) --127 + j*(157) -31 + j*(202) -190 + j*(87) -156 + j*(-146) --85 + j*(-204) --216 + j*(-30) --155 + j*(107) --95 + j*(154) --13 + j*(214) -136 + j*(175) -153 + j*(21) -40 + j*(-1) -65 + j*(89) -175 + j*(22) -105 + j*(-119) --43 + j*(-61) -13 + j*(91) -191 + j*(42) -188 + j*(-163) -1 + j*(-242) --140 + j*(-134) --145 + j*(11) --46 + j*(112) -123 + j*(88) -182 + j*(-113) --4 + j*(-250) --164 + j*(-119) --84 + j*(-23) --111 + j*(-127) --332 + j*(-11) --223 + j*(346) -188 + j*(330) -250 + j*(-14) -39 + j*(-63) -91 + j*(49) -187 + j*(-119) --20 + j*(-245) --148 + j*(-88) --70 + j*(-34) --145 + j*(-76) --208 + j*(101) -6 + j*(201) -101 + j*(0) --80 + j*(-46) --74 + j*(122) -69 + j*(79) --21 + j*(-8) --45 + j*(161) -223 + j*(167) -260 + j*(-165) --73 + j*(-249) --171 + j*(35) -70 + j*(114) -132 + j*(-117) --102 + j*(-209) --268 + j*(-11) --166 + j*(224) -73 + j*(252) -189 + j*(76) -90 + j*(-40) -28 + j*(37) -148 + j*(68) -208 + j*(-92) -79 + j*(-209) --41 + j*(-173) --88 + j*(-124) --132 + j*(-63) --104 + j*(26) --31 + j*(5) --103 + j*(-40) --168 + j*(113) -37 + j*(241) -228 + j*(40) -66 + j*(-176) --133 + j*(-46) --21 + j*(117) -107 + j*(22) -41 + j*(-64) -28 + j*(-28) -63 + j*(-115) --113 + j*(-202) --288 + j*(13) --102 + j*(262) -165 + j*(146) -112 + j*(-84) --59 + j*(-62) --39 + j*(65) -69 + j*(44) -68 + j*(-50) --1 + j*(-81) --45 + j*(-60) --72 + j*(-40) --107 + j*(0) --97 + j*(94) -23 + j*(130) -104 + j*(6) --19 + j*(-107) --163 + j*(2) --98 + j*(163) -32 + j*(159) -57 + j*(105) -67 + j*(107) -103 + j*(98) -129 + j*(96) -221 + j*(78) -284 + j*(-74) -160 + j*(-206) -58 + j*(-151) -107 + j*(-152) -34 + j*(-272) --140 + j*(-206) --98 + j*(-59) --9 + j*(-129) --130 + j*(-213) --245 + j*(-123) --288 + j*(-35) --350 + j*(134) --155 + j*(395) -218 + j*(272) -158 + j*(-80) --105 + j*(11) -93 + j*(211) -281 + j*(-88) --50 + j*(-284) --209 + j*(13) -38 + j*(69) --41 + j*(-163) --296 + j*(27) --74 + j*(295) -156 + j*(88) --33 + j*(-39) --42 + j*(158) -167 + j*(74) -14 + j*(-136) --183 + j*(77) -65 + j*(263) -221 + j*(14) --19 + j*(-74) --25 + j*(204) -338 + j*(187) -400 + j*(-231) -31 + j*(-421) --223 + j*(-202) --164 + j*(-1) --90 + j*(11) --108 + j*(50) --28 + j*(141) -110 + j*(79) -81 + j*(-49) -1 + j*(-29) -44 + j*(-4) -22 + j*(-83) --86 + j*(-19) -19 + j*(105) -155 + j*(-39) --16 + j*(-174) --126 + j*(8) -58 + j*(71) -61 + j*(-107) --94 + j*(-41) -53 + j*(81) -152 + j*(-152) --134 + j*(-249) --212 + j*(27) -13 + j*(31) --108 + j*(-165) --331 + j*(65) --63 + j*(331) -197 + j*(100) -23 + j*(-91) --70 + j*(56) -72 + j*(66) -44 + j*(-62) --47 + j*(-30) --16 + j*(-4) --71 + j*(-36) --115 + j*(84) -42 + j*(141) -95 + j*(-24) --60 + j*(-59) --73 + j*(71) -12 + j*(56) --54 + j*(25) --49 + j*(161) -138 + j*(169) -171 + j*(-16) -31 + j*(-37) -76 + j*(78) -231 + j*(-36) -105 + j*(-274) --192 + j*(-209) --205 + j*(77) -11 + j*(123) -16 + j*(-23) --105 + j*(62) -64 + j*(218) -275 + j*(9) -74 + j*(-238) --168 + j*(-60) --8 + j*(139) -133 + j*(-11) --16 + j*(-84) --25 + j*(78) -161 + j*(52) -138 + j*(-136) --6 + j*(-127) -21 + j*(-45) -83 + j*(-111) -18 + j*(-208) --103 + j*(-223) --221 + j*(-151) --252 + j*(-1) --166 + j*(93) --98 + j*(93) --58 + j*(98) --4 + j*(57) --63 + j*(-6) --138 + j*(103) -16 + j*(211) -146 + j*(52) -10 + j*(-53) --27 + j*(73) -110 + j*(28) --1 + j*(-129) --175 + j*(21) --14 + j*(196) -130 + j*(52) -11 + j*(-21) -27 + j*(103) -193 + j*(16) -107 + j*(-202) --131 + j*(-188) --225 + j*(0) --151 + j*(190) -72 + j*(253) -236 + j*(65) -118 + j*(-120) -0 + j*(-57) -58 + j*(-48) --39 + j*(-142) --183 + j*(23) -5 + j*(203) -180 + j*(36) -63 + j*(-68) -97 + j*(18) -214 + j*(-175) --72 + j*(-381) --351 + j*(-119) --185 + j*(129) --79 + j*(41) --179 + j*(95) --40 + j*(252) -127 + j*(124) -24 + j*(40) -58 + j*(175) -269 + j*(78) -195 + j*(-171) -1 + j*(-156) --3 + j*(-79) --44 + j*(-112) --129 + j*(-7) --21 + j*(110) -84 + j*(32) -48 + j*(-4) -119 + j*(15) -174 + j*(-157) --36 + j*(-284) --210 + j*(-117) --117 + j*(38) --27 + j*(-5) --57 + j*(-45) --81 + j*(-31) --107 + j*(-19) --129 + j*(36) --92 + j*(88) --56 + j*(98) --28 + j*(129) -60 + j*(140) -129 + j*(58) -108 + j*(-37) -47 + j*(-77) --11 + j*(-66) --13 + j*(-17) -44 + j*(-52) --26 + j*(-168) --223 + j*(-115) --238 + j*(111) --64 + j*(192) -21 + j*(105) --16 + j*(61) --45 + j*(96) --6 + j*(173) -145 + j*(181) -225 + j*(-13) -28 + j*(-133) --81 + j*(72) -163 + j*(156) -250 + j*(-125) --13 + j*(-226) --88 + j*(-43) -2 + j*(-64) --158 + j*(-110) --231 + j*(163) -66 + j*(300) -243 + j*(77) -145 + j*(-66) -91 + j*(-82) --3 + j*(-118) --97 + j*(46) -150 + j*(188) -357 + j*(-127) -28 + j*(-403) --263 + j*(-116) --34 + j*(139) -162 + j*(-49) -13 + j*(-190) --71 + j*(-94) --10 + j*(-69) --17 + j*(-113) --30 + j*(-117) --39 + j*(-168) --137 + j*(-205) --234 + j*(-144) --278 + j*(-71) --324 + j*(36) --268 + j*(194) --107 + j*(233) --40 + j*(147) -144 + j*(100) -114 + j*(-139) --59 + j*(-81) -41 + j*(-2) -23 + j*(-161) --189 + j*(-74) --52 + j*(148) -144 + j*(-46) --123 + j*(-207) --264 + j*(122) -91 + j*(254) -206 + j*(-91) --107 + j*(-187) --196 + j*(83) -6 + j*(176) -105 + j*(62) -81 + j*(-24) -15 + j*(-57) --35 + j*(6) -52 + j*(47) -86 + j*(-85) --80 + j*(-120) --107 + j*(52) -46 + j*(39) --36 + j*(-94) --171 + j*(52) -12 + j*(190) -124 + j*(6) --62 + j*(-54) --77 + j*(151) -130 + j*(168) -180 + j*(26) -166 + j*(-25) -178 + j*(-141) --4 + j*(-233) --127 + j*(-46) -69 + j*(38) -97 + j*(-207) --206 + j*(-209) --213 + j*(114) -80 + j*(118) -58 + j*(-122) --129 + j*(-64) --42 + j*(75) -59 + j*(-29) --37 + j*(-95) --54 + j*(-34) --23 + j*(-101) --174 + j*(-157) --306 + j*(5) --240 + j*(180) --135 + j*(243) --26 + j*(291) -132 + j*(257) -208 + j*(124) -208 + j*(8) -157 + j*(-139) --93 + j*(-210) --298 + j*(95) -19 + j*(426) -450 + j*(151) -264 + j*(-317) --165 + j*(-221) --127 + j*(117) -110 + j*(104) -114 + j*(-34) -76 + j*(-50) -64 + j*(-108) --61 + j*(-112) --74 + j*(44) -88 + j*(50) -76 + j*(-103) --59 + j*(-65) -11 + j*(50) -115 + j*(-42) -33 + j*(-141) --35 + j*(-100) --25 + j*(-98) --86 + j*(-113) --129 + j*(-36) --80 + j*(10) --71 + j*(-4) --76 + j*(33) --16 + j*(42) --2 + j*(-22) --56 + j*(-44) --93 + j*(-27) --144 + j*(9) --151 + j*(122) --30 + j*(186) -37 + j*(105) --25 + j*(115) -68 + j*(235) -293 + j*(144) -298 + j*(-127) -99 + j*(-245) --52 + j*(-191) --116 + j*(-89) --85 + j*(19) -25 + j*(21) -33 + j*(-80) --43 + j*(-100) --53 + j*(-90) --119 + j*(-156) --303 + j*(-93) --355 + j*(148) --214 + j*(329) --27 + j*(395) -199 + j*(349) -314 + j*(112) -151 + j*(-49) -52 + j*(86) -244 + j*(121) -284 + j*(-127) -49 + j*(-185) -27 + j*(2) -211 + j*(-42) -151 + j*(-265) --82 + j*(-264) --145 + j*(-88) --41 + j*(-4) -49 + j*(-73) --9 + j*(-200) --190 + j*(-180) --232 + j*(2) --119 + j*(68) --112 + j*(33) --122 + j*(126) -45 + j*(161) -108 + j*(-21) --56 + j*(-84) --106 + j*(52) --6 + j*(88) -16 + j*(47) -35 + j*(50) -67 + j*(-11) --2 + j*(-44) -1 + j*(21) -67 + j*(-56) --99 + j*(-135) --204 + j*(109) -81 + j*(243) -216 + j*(-44) --47 + j*(-130) --43 + j*(114) -233 + j*(11) -84 + j*(-315) --265 + j*(-170) --150 + j*(167) -147 + j*(76) -84 + j*(-208) --208 + j*(-217) --339 + j*(59) --137 + j*(312) -177 + j*(216) -168 + j*(-83) --66 + j*(-107) --75 + j*(45) --13 + j*(2) --144 + j*(21) --92 + j*(252) -191 + j*(226) -193 + j*(-28) -28 + j*(-5) -127 + j*(87) -182 + j*(-74) -2 + j*(-99) -33 + j*(83) -234 + j*(-5) -139 + j*(-223) --50 + j*(-148) -25 + j*(-31) -87 + j*(-139) --49 + j*(-194) --114 + j*(-74) --28 + j*(-21) -13 + j*(-83) --19 + j*(-139) --81 + j*(-182) --221 + j*(-189) --378 + j*(-21) --302 + j*(275) -32 + j*(345) -192 + j*(62) --36 + j*(-93) --155 + j*(137) -107 + j*(244) -225 + j*(-13) -21 + j*(-123) --39 + j*(11) -32 + j*(-8) --66 + j*(-26) --44 + j*(143) -177 + j*(104) -151 + j*(-119) --4 + j*(-110) -28 + j*(-82) --83 + j*(-192) --298 + j*(13) --53 + j*(310) -272 + j*(63) -35 + j*(-238) --210 + j*(-17) --16 + j*(141) -29 + j*(-34) --162 + j*(33) --40 + j*(267) -216 + j*(182) -217 + j*(-12) -163 + j*(-77) -107 + j*(-164) --49 + j*(-154) --57 + j*(-6) -54 + j*(-30) --21 + j*(-124) --98 + j*(-25) --4 + j*(8) --48 + j*(-83) --159 + j*(32) --23 + j*(166) -86 + j*(62) -21 + j*(54) -163 + j*(147) -370 + j*(-109) -130 + j*(-465) --307 + j*(-383) --434 + j*(-24) --293 + j*(241) --41 + j*(349) -219 + j*(228) -253 + j*(-38) -90 + j*(-149) -0 + j*(-105) --21 + j*(-91) --54 + j*(-76) --62 + j*(-71) --137 + j*(-81) --226 + j*(62) --79 + j*(230) -105 + j*(127) -32 + j*(-2) --16 + j*(91) -112 + j*(83) -72 + j*(-52) --34 + j*(34) -112 + j*(119) -197 + j*(-66) -29 + j*(-139) -23 + j*(-28) -93 + j*(-136) --129 + j*(-206) --209 + j*(88) -128 + j*(161) -176 + j*(-214) --231 + j*(-250) --276 + j*(163) -103 + j*(216) -162 + j*(-110) --103 + j*(-170) --168 + j*(8) --94 + j*(54) --115 + j*(67) --83 + j*(164) -49 + j*(171) -99 + j*(70) -49 + j*(5) --25 + j*(11) --71 + j*(113) -41 + j*(254) -279 + j*(206) -356 + j*(-46) -205 + j*(-207) -76 + j*(-194) -20 + j*(-175) --49 + j*(-140) --44 + j*(-54) -33 + j*(-76) --28 + j*(-177) --183 + j*(-119) --182 + j*(59) --43 + j*(129) -66 + j*(73) -86 + j*(-34) -5 + j*(-106) --82 + j*(-42) --15 + j*(33) -47 + j*(-59) --76 + j*(-122) --139 + j*(6) --29 + j*(49) --35 + j*(-45) --131 + j*(8) --66 + j*(96) --30 + j*(40) --101 + j*(95) -33 + j*(218) -203 + j*(63) -78 + j*(-99) -5 + j*(-5) -102 + j*(-70) --103 + j*(-209) --305 + j*(100) -66 + j*(353) -339 + j*(-42) --57 + j*(-307) --301 + j*(69) -21 + j*(284) -190 + j*(57) -82 + j*(-44) -60 + j*(-49) --45 + j*(-98) --144 + j*(104) -140 + j*(253) -336 + j*(-73) -31 + j*(-284) --132 + j*(-40) -67 + j*(16) -7 + j*(-181) --216 + j*(-55) --95 + j*(177) -87 + j*(103) -58 + j*(34) -124 + j*(73) -238 + j*(-86) -78 + j*(-296) --180 + j*(-224) --221 + j*(8) --57 + j*(126) -105 + j*(9) --1 + j*(-199) --282 + j*(-111) --247 + j*(228) -83 + j*(258) -134 + j*(0) --55 + j*(-5) -2 + j*(168) -202 + j*(102) -206 + j*(-102) -62 + j*(-202) --98 + j*(-160) --134 + j*(5) -27 + j*(59) -62 + j*(-136) --194 + j*(-168) --259 + j*(117) --12 + j*(205) -42 + j*(38) --71 + j*(74) -40 + j*(184) -169 + j*(58) -74 + j*(-47) -27 + j*(14) -86 + j*(18) -86 + j*(-35) -77 + j*(-62) -31 + j*(-113) --66 + j*(-48) -53 + j*(76) -242 + j*(-124) --1 + j*(-432) --417 + j*(-264) --421 + j*(142) --186 + j*(296) --6 + j*(315) -218 + j*(226) -247 + j*(-93) --90 + j*(-182) --182 + j*(164) -179 + j*(245) -259 + j*(-111) --62 + j*(-174) --81 + j*(103) -185 + j*(71) -134 + j*(-216) --175 + j*(-194) --214 + j*(105) -35 + j*(205) -169 + j*(27) -64 + j*(-98) --13 + j*(-45) -30 + j*(-47) --57 + j*(-122) --204 + j*(22) --45 + j*(244) -211 + j*(115) -117 + j*(-112) --33 + j*(-10) -135 + j*(69) -196 + j*(-180) --95 + j*(-271) --214 + j*(4) -13 + j*(116) -98 + j*(-71) --56 + j*(-140) --122 + j*(-34) --77 + j*(11) --88 + j*(7) --112 + j*(77) --31 + j*(173) -130 + j*(153) -206 + j*(-4) -139 + j*(-139) -52 + j*(-182) --37 + j*(-235) --233 + j*(-211) --333 + j*(33) --136 + j*(209) -6 + j*(76) --130 + j*(20) --127 + j*(216) -112 + j*(206) -97 + j*(-23) --114 + j*(33) --18 + j*(248) -208 + j*(163) -162 + j*(-18) -74 + j*(20) -156 + j*(33) -157 + j*(-88) -54 + j*(-106) -54 + j*(-64) -59 + j*(-120) --37 + j*(-133) --66 + j*(-51) --35 + j*(-43) --90 + j*(-32) --62 + j*(88) -112 + j*(53) -64 + j*(-175) --239 + j*(-116) --204 + j*(276) -263 + j*(312) -400 + j*(-181) --59 + j*(-414) --345 + j*(-23) --17 + j*(279) -287 + j*(-2) -54 + j*(-317) --267 + j*(-153) --187 + j*(132) -25 + j*(112) -10 + j*(-30) --101 + j*(14) --50 + j*(140) -96 + j*(128) -144 + j*(-4) -58 + j*(-91) --30 + j*(-45) --2 + j*(36) -90 + j*(21) -115 + j*(-74) -66 + j*(-150) --4 + j*(-198) --127 + j*(-223) --272 + j*(-129) --288 + j*(60) --172 + j*(156) --106 + j*(139) --111 + j*(180) --2 + j*(269) -180 + j*(195) -193 + j*(-4) -47 + j*(-75) --20 + j*(1) -14 + j*(30) --6 + j*(3) --56 + j*(64) -12 + j*(162) -153 + j*(139) -195 + j*(6) -124 + j*(-74) -64 + j*(-59) -65 + j*(-44) -59 + j*(-62) -30 + j*(-60) -30 + j*(-37) -40 + j*(-38) -44 + j*(-30) -95 + j*(-29) -142 + j*(-123) -58 + j*(-236) --76 + j*(-217) --99 + j*(-147) --112 + j*(-163) --206 + j*(-144) --247 + j*(-40) --233 + j*(20) --268 + j*(112) --160 + j*(294) -119 + j*(248) -119 + j*(-46) --166 + j*(-35) --129 + j*(279) -225 + j*(253) -252 + j*(-98) --35 + j*(-184) --156 + j*(-9) --127 + j*(107) --74 + j*(223) -131 + j*(286) -298 + j*(88) -164 + j*(-94) -57 + j*(7) -195 + j*(31) -187 + j*(-161) --21 + j*(-151) -23 + j*(42) -228 + j*(-50) -130 + j*(-291) --111 + j*(-240) --89 + j*(-58) -41 + j*(-115) --55 + j*(-274) --294 + j*(-221) --366 + j*(43) --172 + j*(231) -43 + j*(133) --14 + j*(-48) --181 + j*(25) --89 + j*(216) -122 + j*(141) -79 + j*(-52) --66 + j*(-21) --28 + j*(63) --8 + j*(-1) --116 + j*(37) --42 + j*(202) -159 + j*(124) -83 + j*(-76) --100 + j*(16) -22 + j*(194) -196 + j*(66) -77 + j*(-83) --19 + j*(47) -152 + j*(118) -251 + j*(-88) -80 + j*(-239) --86 + j*(-166) --109 + j*(-57) --93 + j*(1) --73 + j*(54) --21 + j*(100) -72 + j*(111) -172 + j*(20) -124 + j*(-136) --50 + j*(-129) --43 + j*(38) -132 + j*(0) -69 + j*(-211) --181 + j*(-151) --145 + j*(109) -105 + j*(105) -136 + j*(-108) --2 + j*(-182) --82 + j*(-158) --173 + j*(-144) --274 + j*(-18) --214 + j*(171) --36 + j*(211) -54 + j*(119) -42 + j*(52) -20 + j*(42) -28 + j*(47) -45 + j*(26) -29 + j*(4) -18 + j*(19) -47 + j*(9) -21 + j*(-30) --14 + j*(29) -117 + j*(64) -194 + j*(-156) --80 + j*(-331) --351 + j*(-86) --207 + j*(208) -8 + j*(154) --31 + j*(71) --18 + j*(165) -136 + j*(132) -124 + j*(-31) -2 + j*(-37) --8 + j*(30) -4 + j*(45) -24 + j*(95) -135 + j*(85) -139 + j*(-47) -35 + j*(-35) -120 + j*(34) -194 + j*(-156) --86 + j*(-270) --250 + j*(62) -107 + j*(274) -376 + j*(-83) -81 + j*(-404) --240 + j*(-239) --210 + j*(-13) --152 + j*(24) --155 + j*(121) -13 + j*(231) -222 + j*(92) -180 + j*(-144) -1 + j*(-199) --95 + j*(-138) --144 + j*(-87) --191 + j*(10) --120 + j*(147) -57 + j*(143) -117 + j*(-29) --23 + j*(-131) --144 + j*(-45) --124 + j*(57) --93 + j*(82) --83 + j*(140) -27 + j*(192) -135 + j*(89) -48 + j*(-26) --49 + j*(83) -102 + j*(208) -302 + j*(53) -222 + j*(-209) --25 + j*(-246) --151 + j*(-85) --100 + j*(69) -42 + j*(111) -156 + j*(-3) -81 + j*(-167) --112 + j*(-141) --125 + j*(42) -30 + j*(71) -41 + j*(-50) --55 + j*(-14) -54 + j*(79) -187 + j*(-110) --51 + j*(-331) --372 + j*(-107) --217 + j*(260) -122 + j*(160) -20 + j*(-132) --268 + j*(17) --103 + j*(351) -269 + j*(233) -226 + j*(-110) --33 + j*(-105) --6 + j*(63) -107 + j*(-15) --10 + j*(-103) --88 + j*(27) -31 + j*(91) -69 + j*(8) -44 + j*(25) -150 + j*(0) -107 + j*(-216) --198 + j*(-200) --223 + j*(147) -117 + j*(201) -166 + j*(-112) --123 + j*(-139) --135 + j*(134) -117 + j*(157) -165 + j*(-52) -25 + j*(-124) --57 + j*(-50) --33 + j*(39) -78 + j*(47) -110 + j*(-95) --59 + j*(-139) --91 + j*(61) -158 + j*(62) -148 + j*(-249) --190 + j*(-263) --224 + j*(35) --13 + j*(33) --105 + j*(-115) --235 + j*(47) --71 + j*(166) --21 + j*(40) --129 + j*(108) -42 + j*(244) -213 + j*(25) --16 + j*(-142) --153 + j*(88) -67 + j*(202) -175 + j*(26) -91 + j*(-64) -47 + j*(-93) --87 + j*(-119) --182 + j*(95) -90 + j*(248) -279 + j*(-56) --25 + j*(-264) --223 + j*(11) --1 + j*(165) -72 + j*(1) --47 + j*(19) -42 + j*(117) -108 + j*(-4) --17 + j*(0) -78 + j*(148) -271 + j*(-11) -112 + j*(-221) --30 + j*(-89) -124 + j*(-91) --13 + j*(-344) --397 + j*(-146) --210 + j*(320) -266 + j*(155) -98 + j*(-298) --337 + j*(-121) --184 + j*(305) -194 + j*(218) -178 + j*(-49) -65 + j*(-50) -132 + j*(-78) -56 + j*(-267) --237 + j*(-258) --377 + j*(42) --192 + j*(322) -141 + j*(327) -325 + j*(55) -189 + j*(-217) --54 + j*(-221) --131 + j*(-95) --144 + j*(-40) --175 + j*(66) --47 + j*(191) -121 + j*(77) -18 + j*(-81) --108 + j*(42) -54 + j*(137) -127 + j*(-64) --112 + j*(-124) --172 + j*(144) -100 + j*(218) -187 + j*(-15) -14 + j*(-90) --21 + j*(30) -62 + j*(21) -18 + j*(-42) --34 + j*(35) -68 + j*(101) -170 + j*(2) -119 + j*(-130) -6 + j*(-136) --16 + j*(-76) -10 + j*(-100) --74 + j*(-148) --179 + j*(-42) --91 + j*(98) -42 + j*(25) --37 + j*(-88) --147 + j*(-1) --86 + j*(103) --18 + j*(102) -36 + j*(106) -126 + j*(17) -11 + j*(-145) --206 + j*(-6) --47 + j*(245) -207 + j*(66) --15 + j*(-161) --214 + j*(128) -122 + j*(326) -318 + j*(7) -70 + j*(-118) -91 + j*(78) -311 + j*(-99) -57 + j*(-383) --241 + j*(-135) --14 + j*(94) -115 + j*(-156) --186 + j*(-227) --252 + j*(89) -21 + j*(159) -73 + j*(-37) --58 + j*(-59) --62 + j*(23) --24 + j*(32) -8 + j*(34) -42 + j*(-37) --79 + j*(-105) --193 + j*(67) -2 + j*(228) -190 + j*(57) -70 + j*(-106) --11 + j*(-27) -69 + j*(-54) --45 + j*(-185) --231 + j*(-43) --115 + j*(156) -37 + j*(57) --93 + j*(-25) --156 + j*(170) -78 + j*(279) -248 + j*(86) -146 + j*(-98) -6 + j*(-70) -16 + j*(18) -95 + j*(-5) -75 + j*(-119) --78 + j*(-141) --161 + j*(25) --20 + j*(162) -144 + j*(63) -93 + j*(-98) --44 + j*(-76) --37 + j*(32) -53 + j*(35) -81 + j*(-43) -35 + j*(-105) --49 + j*(-117) --122 + j*(-47) --89 + j*(52) --2 + j*(38) --39 + j*(-33) --122 + j*(45) --23 + j*(166) -119 + j*(76) -28 + j*(-49) --66 + j*(86) -141 + j*(190) -303 + j*(-67) -58 + j*(-293) --188 + j*(-107) --60 + j*(103) -87 + j*(5) --7 + j*(-75) --25 + j*(29) -105 + j*(-1) -59 + j*(-175) --141 + j*(-156) --177 + j*(27) --63 + j*(100) -4 + j*(71) -35 + j*(47) -62 + j*(-2) -26 + j*(-59) --28 + j*(-43) --9 + j*(-8) -21 + j*(-62) --70 + j*(-139) --241 + j*(-59) --252 + j*(199) -17 + j*(357) -298 + j*(173) -252 + j*(-141) -3 + j*(-206) --95 + j*(-69) --40 + j*(-15) --54 + j*(-54) --133 + j*(-16) --143 + j*(107) --35 + j*(205) -133 + j*(177) -202 + j*(1) -71 + j*(-123) --56 + j*(-41) -13 + j*(59) -94 + j*(-21) -19 + j*(-98) --47 + j*(-52) --40 + j*(-37) --110 + j*(-35) --149 + j*(111) -23 + j*(215) -165 + j*(74) -76 + j*(-56) --11 + j*(1) -30 + j*(45) -23 + j*(37) -51 + j*(127) -254 + j*(113) -326 + j*(-168) -64 + j*(-348) --156 + j*(-192) --112 + j*(-25) --44 + j*(-9) --15 + j*(15) -85 + j*(-18) -57 + j*(-182) --154 + j*(-184) --199 + j*(30) --31 + j*(102) -40 + j*(6) -31 + j*(-35) -49 + j*(-125) --118 + j*(-252) --381 + j*(-74) --271 + j*(275) -63 + j*(257) -85 + j*(16) --61 + j*(23) --1 + j*(112) -55 + j*(21) --43 + j*(4) --15 + j*(107) -101 + j*(37) --3 + j*(-95) --155 + j*(18) --65 + j*(187) -84 + j*(152) -90 + j*(71) -85 + j*(79) -158 + j*(64) -202 + j*(-56) -105 + j*(-194) --98 + j*(-185) --185 + j*(19) --22 + j*(162) -120 + j*(41) -18 + j*(-66) --49 + j*(47) -81 + j*(86) -91 + j*(-52) --56 + j*(-18) -25 + j*(170) -280 + j*(81) -242 + j*(-219) --45 + j*(-251) --104 + j*(-11) -115 + j*(41) -188 + j*(-203) --66 + j*(-356) --310 + j*(-163) --231 + j*(110) --1 + j*(123) -53 + j*(-40) --52 + j*(-109) --141 + j*(-64) --173 + j*(28) --115 + j*(134) -21 + j*(132) -54 + j*(7) --55 + j*(-27) --80 + j*(75) -13 + j*(101) -42 + j*(37) -21 + j*(30) -62 + j*(24) -64 + j*(-76) --80 + j*(-126) --209 + j*(16) --119 + j*(219) -111 + j*(224) -198 + j*(27) -74 + j*(-86) -3 + j*(-23) -49 + j*(-32) --34 + j*(-107) --163 + j*(16) --45 + j*(180) -108 + j*(92) -33 + j*(-2) -5 + j*(95) -135 + j*(96) -144 + j*(-18) -107 + j*(-13) -182 + j*(-74) -67 + j*(-247) --175 + j*(-125) --54 + j*(132) -190 + j*(-6) -40 + j*(-233) --161 + j*(-98) --61 + j*(39) --20 + j*(-42) --102 + j*(4) --11 + j*(105) -84 + j*(20) -41 + j*(-22) -104 + j*(-15) -120 + j*(-202) --148 + j*(-276) --279 + j*(-10) --69 + j*(116) --6 + j*(-48) --163 + j*(-61) --185 + j*(83) --119 + j*(146) --56 + j*(219) -141 + j*(226) -251 + j*(-26) -21 + j*(-221) --214 + j*(-74) --190 + j*(148) --60 + j*(253) -116 + j*(282) -306 + j*(153) -316 + j*(-95) -158 + j*(-246) --43 + j*(-279) --268 + j*(-133) --239 + j*(223) -180 + j*(308) -349 + j*(-122) --64 + j*(-347) --322 + j*(26) --8 + j*(297) -247 + j*(64) -94 + j*(-145) --49 + j*(-45) -32 + j*(45) -108 + j*(-38) -32 + j*(-130) --74 + j*(-74) --28 + j*(23) -49 + j*(-39) --59 + j*(-112) --149 + j*(50) -41 + j*(172) -185 + j*(-4) -66 + j*(-120) -44 + j*(-49) -133 + j*(-151) --36 + j*(-321) --262 + j*(-193) --228 + j*(-13) --184 + j*(-14) --239 + j*(48) --181 + j*(162) --107 + j*(170) --72 + j*(226) -110 + j*(231) -163 + j*(-16) --125 + j*(-67) --160 + j*(276) -224 + j*(334) -330 + j*(-10) -110 + j*(-105) -117 + j*(-16) -158 + j*(-151) --41 + j*(-218) --127 + j*(-69) --90 + j*(-40) --190 + j*(7) --132 + j*(233) -139 + j*(206) -105 + j*(-23) --70 + j*(91) -141 + j*(276) -378 + j*(51) -246 + j*(-183) -138 + j*(-158) -154 + j*(-242) --54 + j*(-347) --252 + j*(-144) --119 + j*(59) -10 + j*(-28) --83 + j*(-84) --122 + j*(31) --16 + j*(100) -103 + j*(54) -160 + j*(-99) -23 + j*(-279) --250 + j*(-215) --277 + j*(72) --40 + j*(152) -33 + j*(-25) --109 + j*(-80) --172 + j*(23) --148 + j*(94) --120 + j*(180) -33 + j*(251) -209 + j*(100) -108 + j*(-134) --139 + j*(-85) --134 + j*(147) -62 + j*(185) -126 + j*(57) -85 + j*(6) -94 + j*(-25) -28 + j*(-120) --146 + j*(-66) --144 + j*(151) -54 + j*(213) -146 + j*(105) -148 + j*(69) -239 + j*(5) -206 + j*(-204) --40 + j*(-253) --141 + j*(-56) --26 + j*(25) --9 + j*(-23) --25 + j*(31) -88 + j*(24) -68 + j*(-133) --115 + j*(-102) --71 + j*(83) -107 + j*(17) -22 + j*(-158) --146 + j*(-75) --86 + j*(59) --18 + j*(10) --89 + j*(6) --71 + j*(113) -38 + j*(118) -62 + j*(61) -79 + j*(71) -175 + j*(26) -182 + j*(-141) -27 + j*(-250) --154 + j*(-200) --242 + j*(-35) --169 + j*(148) -28 + j*(182) -119 + j*(23) --4 + j*(-71) --80 + j*(55) -78 + j*(136) -201 + j*(-40) -51 + j*(-215) --136 + j*(-129) --115 + j*(15) --48 + j*(14) --65 + j*(13) --32 + j*(52) -6 + j*(-6) --92 + j*(-28) --108 + j*(125) -95 + j*(154) -145 + j*(-75) --81 + j*(-149) --168 + j*(36) --63 + j*(98) --88 + j*(78) --85 + j*(232) -168 + j*(283) -300 + j*(21) -99 + j*(-140) --28 + j*(1) -87 + j*(86) -153 + j*(6) -146 + j*(-33) -196 + j*(-98) -144 + j*(-267) --88 + j*(-317) --242 + j*(-145) --199 + j*(22) --127 + j*(65) --105 + j*(106) --24 + j*(184) -145 + j*(170) -253 + j*(-1) -181 + j*(-197) -1 + j*(-265) --160 + j*(-197) --226 + j*(-42) --148 + j*(98) --10 + j*(91) -0 + j*(-11) --71 + j*(-3) --41 + j*(52) --11 + j*(0) --92 + j*(-5) --85 + j*(107) -28 + j*(93) --16 + j*(7) --84 + j*(111) -69 + j*(193) -167 + j*(37) -43 + j*(-35) -47 + j*(66) -161 + j*(-15) -35 + j*(-163) --132 + j*(-27) --15 + j*(130) -108 + j*(49) -64 + j*(-9) -86 + j*(22) -136 + j*(-57) -55 + j*(-124) -25 + j*(-78) -64 + j*(-126) --51 + j*(-210) --187 + j*(-104) --148 + j*(22) --120 + j*(35) --128 + j*(148) -94 + j*(257) -345 + j*(11) -172 + j*(-356) --223 + j*(-314) --296 + j*(6) --100 + j*(103) --70 + j*(-10) --178 + j*(45) --81 + j*(194) -84 + j*(86) --57 + j*(-71) --226 + j*(136) -33 + j*(346) -279 + j*(84) -23 + j*(-144) --164 + j*(141) -165 + j*(317) -367 + j*(-18) -89 + j*(-231) --88 + j*(-35) -35 + j*(93) -132 + j*(57) -219 + j*(1) -264 + j*(-218) --21 + j*(-406) --325 + j*(-150) --140 + j*(187) -168 + j*(58) -76 + j*(-210) --147 + j*(-161) --148 + j*(-8) --74 + j*(6) --89 + j*(-23) --144 + j*(18) --127 + j*(123) -2 + j*(157) -58 + j*(49) --41 + j*(27) --10 + j*(156) -165 + j*(92) -88 + j*(-93) --71 + j*(11) -91 + j*(141) -202 + j*(-65) --13 + j*(-148) --18 + j*(62) -214 + j*(-37) -35 + j*(-320) --281 + j*(-126) --102 + j*(167) -122 + j*(-16) --92 + j*(-170) --205 + j*(63) -10 + j*(156) -71 + j*(-11) --37 + j*(-30) --14 + j*(35) -26 + j*(-16) --26 + j*(-56) --78 + j*(-49) --167 + j*(5) --163 + j*(206) -111 + j*(287) -266 + j*(14) -36 + j*(-153) --81 + j*(48) -132 + j*(109) -180 + j*(-126) --32 + j*(-206) --134 + j*(-86) --135 + j*(-16) --150 + j*(71) --54 + j*(168) -60 + j*(118) -49 + j*(54) -72 + j*(72) -124 + j*(-14) -5 + j*(-96) --78 + j*(39) -68 + j*(103) -100 + j*(-56) --78 + j*(-47) --35 + j*(161) -194 + j*(110) -156 + j*(-115) --33 + j*(-79) -11 + j*(81) -156 + j*(53) -188 + j*(-41) -220 + j*(-119) -189 + j*(-305) --71 + j*(-407) --284 + j*(-194) --153 + j*(18) -1 + j*(-100) --168 + j*(-241) --371 + j*(-59) --262 + j*(197) --33 + j*(185) --1 + j*(25) --129 + j*(-14) --205 + j*(121) --92 + j*(288) -154 + j*(258) -230 + j*(4) -18 + j*(-135) --125 + j*(29) -9 + j*(150) -98 + j*(33) --13 + j*(-10) --10 + j*(112) -136 + j*(90) -122 + j*(-68) --18 + j*(-75) --45 + j*(35) -28 + j*(87) -118 + j*(69) -181 + j*(-52) -69 + j*(-202) --136 + j*(-134) --113 + j*(66) -42 + j*(57) -8 + j*(-47) --66 + j*(23) -25 + j*(87) -83 + j*(7) -42 + j*(-22) -74 + j*(-25) -54 + j*(-136) --122 + j*(-134) --162 + j*(60) -3 + j*(125) -60 + j*(15) --7 + j*(-12) --16 + j*(25) --18 + j*(44) -15 + j*(123) -188 + j*(107) -230 + j*(-129) --8 + j*(-223) --100 + j*(-18) -85 + j*(27) -83 + j*(-168) --118 + j*(-143) --72 + j*(44) -106 + j*(-39) -4 + j*(-240) --216 + j*(-181) --240 + j*(-13) --204 + j*(47) --207 + j*(129) --109 + j*(250) -64 + j*(228) -132 + j*(100) -86 + j*(10) -14 + j*(3) --6 + j*(80) -102 + j*(127) -205 + j*(6) -120 + j*(-132) -23 + j*(-95) -71 + j*(-92) -2 + j*(-221) --213 + j*(-148) --161 + j*(94) -59 + j*(23) --74 + j*(-202) --357 + j*(-33) --240 + j*(288) -18 + j*(272) -37 + j*(175) -105 + j*(233) -291 + j*(98) -181 + j*(-177) --100 + j*(-116) --73 + j*(117) -91 + j*(106) -87 + j*(23) -88 + j*(41) -129 + j*(-18) -35 + j*(-51) -51 + j*(93) -299 + j*(35) -273 + j*(-335) --156 + j*(-414) --351 + j*(-25) --69 + j*(227) -180 + j*(63) -119 + j*(-141) --9 + j*(-163) --68 + j*(-130) --117 + j*(-95) --148 + j*(-23) --117 + j*(53) --54 + j*(87) -18 + j*(79) -74 + j*(8) -27 + j*(-95) --106 + j*(-81) --122 + j*(64) -18 + j*(103) -67 + j*(-23) --38 + j*(-62) --52 + j*(15) --5 + j*(-18) --100 + j*(-43) --124 + j*(118) -87 + j*(151) -124 + j*(-83) --111 + j*(-116) --126 + j*(108) -68 + j*(95) -16 + j*(-65) --108 + j*(23) -4 + j*(105) -25 + j*(-23) --137 + j*(26) --43 + j*(242) -209 + j*(152) -157 + j*(-90) --29 + j*(-62) --1 + j*(57) -65 + j*(22) -33 + j*(-6) -37 + j*(25) -71 + j*(4) -57 + j*(-27) -45 + j*(-31) -33 + j*(-45) -14 + j*(-37) -20 + j*(-40) --26 + j*(-62) --83 + j*(25) -33 + j*(124) -168 + j*(6) -71 + j*(-131) --31 + j*(-49) -61 + j*(-3) -76 + j*(-119) --37 + j*(-129) --37 + j*(-59) --21 + j*(-105) --117 + j*(-103) --119 + j*(0) --52 + j*(-21) --143 + j*(-62) --216 + j*(88) --84 + j*(226) -62 + j*(204) -172 + j*(158) -307 + j*(4) -238 + j*(-293) --97 + j*(-386) --315 + j*(-170) --280 + j*(40) --205 + j*(124) --131 + j*(193) --19 + j*(206) -49 + j*(155) -71 + j*(120) -98 + j*(83) -88 + j*(44) -91 + j*(46) -132 + j*(-2) -78 + j*(-77) -6 + j*(-24) -94 + j*(13) -116 + j*(-141) --91 + j*(-177) --135 + j*(46) -101 + j*(64) -78 + j*(-226) --296 + j*(-205) --355 + j*(235) -74 + j*(406) -328 + j*(66) -108 + j*(-200) --114 + j*(-77) --45 + j*(81) -49 + j*(34) -9 + j*(-13) --10 + j*(21) -1 + j*(23) --32 + j*(61) -52 + j*(161) -234 + j*(83) -208 + j*(-136) -31 + j*(-148) -47 + j*(-47) -117 + j*(-138) --10 + j*(-226) --93 + j*(-142) --71 + j*(-156) --241 + j*(-191) --377 + j*(94) --81 + j*(344) -216 + j*(110) -48 + j*(-162) --172 + j*(-31) --73 + j*(142) -57 + j*(87) -47 + j*(13) -22 + j*(-12) --25 + j*(-16) --24 + j*(68) -117 + j*(53) -107 + j*(-164) --175 + j*(-194) --265 + j*(111) -1 + j*(253) -161 + j*(64) -62 + j*(-62) -4 + j*(-42) --28 + j*(-76) --167 + j*(-33) --160 + j*(195) -110 + j*(252) -217 + j*(-8) --30 + j*(-126) --147 + j*(141) -146 + j*(299) -387 + j*(37) -243 + j*(-246) -35 + j*(-247) --33 + j*(-213) --173 + j*(-204) --295 + j*(11) --115 + j*(234) -114 + j*(135) -74 + j*(-23) -9 + j*(18) -79 + j*(5) -8 + j*(-88) --105 + j*(53) -108 + j*(214) -368 + j*(-23) -211 + j*(-374) --131 + j*(-378) --259 + j*(-180) --253 + j*(-60) --255 + j*(34) --210 + j*(148) --110 + j*(215) -11 + j*(240) -160 + j*(177) -216 + j*(-8) -86 + j*(-150) --68 + j*(-105) --78 + j*(-5) --49 + j*(3) --88 + j*(13) --98 + j*(117) -33 + j*(196) -191 + j*(102) -180 + j*(-88) -23 + j*(-161) --81 + j*(-76) --59 + j*(-5) --49 + j*(-9) --93 + j*(25) --62 + j*(125) -76 + j*(147) -159 + j*(25) -98 + j*(-92) -0 + j*(-98) --47 + j*(-64) --97 + j*(-25) --108 + j*(90) -31 + j*(173) -175 + j*(49) -82 + j*(-114) --69 + j*(-41) --1 + j*(96) -131 + j*(36) -105 + j*(-78) -41 + j*(-94) -9 + j*(-105) --73 + j*(-95) --102 + j*(18) -3 + j*(81) -83 + j*(25) -106 + j*(-34) -129 + j*(-136) -4 + j*(-281) --235 + j*(-223) --278 + j*(6) --155 + j*(91) --127 + j*(73) --122 + j*(136) --34 + j*(174) -15 + j*(154) -86 + j*(183) -236 + j*(89) -199 + j*(-133) -11 + j*(-152) -20 + j*(-77) -4 + j*(-209) --286 + j*(-191) --341 + j*(189) -17 + j*(314) -130 + j*(55) --38 + j*(45) -91 + j*(190) -264 + j*(-47) --21 + j*(-260) --262 + j*(22) --18 + j*(275) -221 + j*(108) -154 + j*(-83) -52 + j*(-103) --15 + j*(-94) --64 + j*(-11) -44 + j*(52) -108 + j*(-109) --117 + j*(-198) --267 + j*(60) --30 + j*(270) -205 + j*(99) -99 + j*(-131) --123 + j*(-71) --119 + j*(173) -160 + j*(271) -397 + j*(8) -227 + j*(-342) --134 + j*(-293) --158 + j*(-21) -2 + j*(-22) --86 + j*(-103) --139 + j*(74) -104 + j*(113) -129 + j*(-175) --195 + j*(-192) --213 + j*(151) -124 + j*(177) -165 + j*(-131) --93 + j*(-189) --161 + j*(-6) --66 + j*(54) --33 + j*(25) --26 + j*(12) --36 + j*(-13) --82 + j*(9) --55 + j*(66) --14 + j*(37) --62 + j*(30) --41 + j*(111) -63 + j*(80) -17 + j*(-19) --72 + j*(60) -42 + j*(157) -161 + j*(45) -98 + j*(-74) -28 + j*(-83) --31 + j*(-104) --149 + j*(-33) --94 + j*(147) -101 + j*(103) -35 + j*(-83) --158 + j*(25) --26 + j*(250) -224 + j*(148) -187 + j*(-78) -29 + j*(-98) --18 + j*(-13) -12 + j*(62) -127 + j*(79) -210 + j*(-69) -71 + j*(-202) --48 + j*(-101) -40 + j*(-66) --28 + j*(-208) --261 + j*(-81) --141 + j*(224) -177 + j*(142) -123 + j*(-127) --58 + j*(-62) -45 + j*(30) -76 + j*(-122) --115 + j*(-110) --59 + j*(100) -177 + j*(4) -77 + j*(-275) --228 + j*(-226) --267 + j*(42) --95 + j*(151) -31 + j*(91) -57 + j*(-20) --27 + j*(-105) --147 + j*(-56) --144 + j*(71) --50 + j*(106) --7 + j*(58) --29 + j*(24) --67 + j*(45) --49 + j*(118) -65 + j*(116) -86 + j*(-36) --112 + j*(-77) --193 + j*(165) -64 + j*(317) -276 + j*(114) -177 + j*(-104) -25 + j*(-93) --6 + j*(-34) --25 + j*(0) -8 + j*(62) -98 + j*(21) -41 + j*(-95) --111 + j*(-27) --52 + j*(167) -162 + j*(155) -220 + j*(-29) -118 + j*(-123) -54 + j*(-117) -21 + j*(-127) --53 + j*(-118) --95 + j*(-32) --35 + j*(44) -45 + j*(13) -33 + j*(-52) --14 + j*(-35) -33 + j*(7) -99 + j*(-81) -2 + j*(-207) --172 + j*(-160) --208 + j*(-7) --146 + j*(72) --112 + j*(112) --35 + j*(176) -103 + j*(151) -158 + j*(18) -99 + j*(-81) -11 + j*(-106) --61 + j*(-59) --44 + j*(31) -65 + j*(18) -53 + j*(-113) --81 + j*(-117) --83 + j*(-16) --30 + j*(-77) --202 + j*(-127) --324 + j*(141) --44 + j*(362) -228 + j*(146) -90 + j*(-93) --62 + j*(8) -55 + j*(76) -70 + j*(-87) --134 + j*(-94) --181 + j*(119) --22 + j*(212) -74 + j*(162) -115 + j*(141) -197 + j*(92) -218 + j*(-27) -170 + j*(-106) -127 + j*(-173) -2 + j*(-251) --190 + j*(-165) --203 + j*(62) --20 + j*(153) -93 + j*(51) -58 + j*(-40) -6 + j*(-46) --22 + j*(-21) --3 + j*(30) -86 + j*(17) -95 + j*(-126) --79 + j*(-179) --173 + j*(-15) --42 + j*(74) --4 + j*(-47) --164 + j*(-27) --126 + j*(191) -116 + j*(171) -101 + j*(-45) --76 + j*(13) -52 + j*(183) -247 + j*(13) -79 + j*(-192) --83 + j*(-44) -78 + j*(41) -103 + j*(-173) --161 + j*(-172) --162 + j*(106) -95 + j*(105) -82 + j*(-119) --99 + j*(-95) --67 + j*(33) --4 + j*(-14) --74 + j*(-21) --40 + j*(69) -55 + j*(6) --31 + j*(-93) --138 + j*(-1) --71 + j*(106) -7 + j*(80) -4 + j*(54) -16 + j*(66) -38 + j*(67) -89 + j*(71) -165 + j*(-13) -92 + j*(-161) --76 + j*(-122) --33 + j*(4) -47 + j*(-105) --160 + j*(-189) --305 + j*(81) --49 + j*(291) -180 + j*(107) -85 + j*(-82) --24 + j*(-65) --71 + j*(-59) --182 + j*(24) --113 + j*(245) -162 + j*(235) -211 + j*(-2) -82 + j*(-57) -105 + j*(-40) -57 + j*(-190) --214 + j*(-143) --218 + j*(195) -119 + j*(257) -211 + j*(-23) --3 + j*(-104) --58 + j*(68) -81 + j*(122) -161 + j*(34) -153 + j*(-53) -96 + j*(-107) -34 + j*(-81) -81 + j*(-36) -146 + j*(-136) -33 + j*(-271) --147 + j*(-221) --185 + j*(-76) --133 + j*(-6) --98 + j*(9) --80 + j*(22) --57 + j*(44) -0 + j*(50) -52 + j*(-19) --2 + j*(-106) --92 + j*(-95) --130 + j*(-57) --187 + j*(-7) --173 + j*(144) -32 + j*(171) -71 + j*(-71) --226 + j*(-107) --287 + j*(241) -47 + j*(349) -146 + j*(107) -4 + j*(114) -156 + j*(236) -326 + j*(-4) -98 + j*(-211) --76 + j*(-43) -40 + j*(45) -30 + j*(-45) --41 + j*(55) -136 + j*(119) -220 + j*(-103) -8 + j*(-214) --111 + j*(-71) --53 + j*(21) --6 + j*(43) -85 + j*(30) -97 + j*(-129) --117 + j*(-163) --171 + j*(70) -44 + j*(124) -54 + j*(-39) --52 + j*(37) -140 + j*(110) -220 + j*(-192) --144 + j*(-316) --315 + j*(39) --25 + j*(219) -111 + j*(18) --19 + j*(-42) -4 + j*(44) -74 + j*(-40) --48 + j*(-110) --127 + j*(16) --18 + j*(100) -57 + j*(18) --7 + j*(-45) --74 + j*(11) --25 + j*(96) -80 + j*(71) -81 + j*(-37) --18 + j*(-50) --22 + j*(45) -85 + j*(44) -107 + j*(-78) --13 + j*(-150) --145 + j*(-63) --115 + j*(125) -119 + j*(172) -253 + j*(-79) -37 + j*(-286) --185 + j*(-141) --96 + j*(16) --42 + j*(-79) --195 + j*(-61) --161 + j*(144) -57 + j*(105) --1 + j*(-112) --246 + j*(-51) --245 + j*(218) --22 + j*(330) -162 + j*(235) -211 + j*(70) -119 + j*(-49) -3 + j*(-13) -25 + j*(96) -150 + j*(94) -206 + j*(-46) -86 + j*(-180) --112 + j*(-100) --64 + j*(151) -252 + j*(136) -301 + j*(-232) --54 + j*(-372) --244 + j*(-119) --134 + j*(26) --115 + j*(15) --107 + j*(129) -71 + j*(166) -145 + j*(18) -98 + j*(-38) -134 + j*(-103) --1 + j*(-272) --283 + j*(-120) --150 + j*(210) -165 + j*(83) -21 + j*(-183) --189 + j*(-12) --2 + j*(131) -64 + j*(-58) --126 + j*(-49) --59 + j*(136) -103 + j*(37) --17 + j*(-81) --87 + j*(56) -59 + j*(99) -103 + j*(-33) -22 + j*(-93) --52 + j*(-93) --134 + j*(-23) --73 + j*(110) -72 + j*(34) --58 + j*(-106) --211 + j*(92) -29 + j*(271) -210 + j*(41) -16 + j*(-95) --42 + j*(75) -119 + j*(57) -55 + j*(-96) --86 + j*(-13) --23 + j*(100) -32 + j*(108) -118 + j*(181) -371 + j*(95) -402 + j*(-281) -74 + j*(-475) --175 + j*(-357) --277 + j*(-229) --358 + j*(-48) --234 + j*(166) --27 + j*(107) --109 + j*(-28) --217 + j*(129) --30 + j*(271) -136 + j*(125) -71 + j*(-9) --1 + j*(-15) --70 + j*(-4) --133 + j*(132) -42 + j*(294) -303 + j*(142) -223 + j*(-158) --55 + j*(-142) --59 + j*(102) -181 + j*(112) -231 + j*(-144) --11 + j*(-252) --147 + j*(-62) -1 + j*(39) -33 + j*(-119) --177 + j*(-115) --193 + j*(136) -23 + j*(185) -57 + j*(69) -38 + j*(128) -215 + j*(129) -273 + j*(-96) -122 + j*(-198) -69 + j*(-190) --35 + j*(-276) --267 + j*(-134) --122 + j*(179) -229 + j*(28) -83 + j*(-345) --271 + j*(-250) --245 + j*(-14) --210 + j*(-30) --313 + j*(112) --86 + j*(327) -173 + j*(93) --69 + j*(-135) --255 + j*(141) -42 + j*(303) -182 + j*(20) --82 + j*(-75) --145 + j*(193) -121 + j*(270) -237 + j*(54) -108 + j*(-70) -25 + j*(-13) -55 + j*(12) -28 + j*(-23) --34 + j*(63) -120 + j*(189) -352 + j*(4) -215 + j*(-322) --115 + j*(-276) --127 + j*(-49) --33 + j*(-69) --134 + j*(-77) --108 + j*(78) -27 + j*(11) --137 + j*(-69) --186 + j*(235) -243 + j*(309) -369 + j*(-182) --112 + j*(-344) --274 + j*(80) -69 + j*(216) -162 + j*(-28) -27 + j*(-59) -87 + j*(-18) -86 + j*(-177) --136 + j*(-192) --197 + j*(26) --31 + j*(121) -74 + j*(19) -27 + j*(-87) --86 + j*(-85) --127 + j*(34) --18 + j*(105) -66 + j*(24) -24 + j*(-49) --16 + j*(-54) --59 + j*(-66) --125 + j*(-4) --54 + j*(88) -26 + j*(-8) --124 + j*(-73) --205 + j*(136) -11 + j*(251) -134 + j*(88) -36 + j*(11) -19 + j*(73) -58 + j*(71) -84 + j*(89) -207 + j*(41) -176 + j*(-191) --116 + j*(-194) --131 + j*(103) -144 + j*(100) -114 + j*(-139) --59 + j*(-81) -41 + j*(-2) -23 + j*(-161) --189 + j*(-74) --52 + j*(148) -144 + j*(-46) --123 + j*(-207) --264 + j*(122) -91 + j*(254) -206 + j*(-91) --107 + j*(-187) --196 + j*(83) -6 + j*(176) -105 + j*(62) -81 + j*(-24) -15 + j*(-57) --35 + j*(6) -52 + j*(47) -86 + j*(-85) --80 + j*(-120) --107 + j*(52) -46 + j*(39) --36 + j*(-94) --171 + j*(52) -12 + j*(190) -124 + j*(6) --62 + j*(-54) --77 + j*(151) -130 + j*(168) -180 + j*(26) -166 + j*(-25) -178 + j*(-141) --4 + j*(-233) --127 + j*(-46) -69 + j*(38) -97 + j*(-207) --206 + j*(-209) --213 + j*(114) -80 + j*(118) -58 + j*(-122) --129 + j*(-64) --42 + j*(75) -59 + j*(-29) --37 + j*(-95) --54 + j*(-34) --23 + j*(-101) --174 + j*(-157) --306 + j*(5) --240 + j*(180) --135 + j*(243) --26 + j*(291) -132 + j*(257) -208 + j*(124) -208 + j*(8) -157 + j*(-139) --93 + j*(-210) --298 + j*(95) -19 + j*(426) -450 + j*(151) -264 + j*(-317) --165 + j*(-221) --127 + j*(117) -110 + j*(104) -114 + j*(-34) -76 + j*(-50) -64 + j*(-108) --61 + j*(-112) --74 + j*(44) -88 + j*(50) -76 + j*(-103) --59 + j*(-65) -11 + j*(50) -115 + j*(-42) -33 + j*(-141) --35 + j*(-100) --25 + j*(-98) --86 + j*(-113) --129 + j*(-36) --80 + j*(10) --71 + j*(-4) --76 + j*(33) --16 + j*(42) --2 + j*(-22) --56 + j*(-44) --93 + j*(-27) --144 + j*(9) --151 + j*(122) --30 + j*(186) -37 + j*(105) --25 + j*(115) -68 + j*(235) -293 + j*(144) -298 + j*(-127) -99 + j*(-245) --52 + j*(-191) --116 + j*(-89) --85 + j*(19) -25 + j*(21) -33 + j*(-80) --43 + j*(-100) --53 + j*(-90) --119 + j*(-156) --303 + j*(-93) --355 + j*(148) --214 + j*(329) --27 + j*(395) -199 + j*(349) -314 + j*(112) -151 + j*(-49) -52 + j*(86) -244 + j*(121) -284 + j*(-127) -49 + j*(-185) -27 + j*(2) -211 + j*(-42) -151 + j*(-265) --82 + j*(-264) --145 + j*(-88) --41 + j*(-4) -49 + j*(-73) --9 + j*(-200) --190 + j*(-180) --232 + j*(2) --119 + j*(68) --112 + j*(33) --122 + j*(126) -45 + j*(161) -108 + j*(-21) --56 + j*(-84) --106 + j*(52) --6 + j*(88) -16 + j*(47) -35 + j*(50) -67 + j*(-11) --2 + j*(-44) -1 + j*(21) -67 + j*(-56) --99 + j*(-135) --204 + j*(109) -81 + j*(243) -216 + j*(-44) --47 + j*(-130) -64 + j*(-24) -41 + j*(-137) --82 + j*(-142) --141 + j*(-64) --153 + j*(28) --67 + j*(131) -93 + j*(62) -26 + j*(-125) --173 + j*(-42) --63 + j*(158) -138 + j*(8) --60 + j*(-206) --307 + j*(6) --136 + j*(267) -69 + j*(159) --29 + j*(66) --37 + j*(230) -202 + j*(243) -265 + j*(5) -98 + j*(-65) -90 + j*(48) -213 + j*(-6) -160 + j*(-149) -56 + j*(-121) -119 + j*(-106) -91 + j*(-280) --187 + j*(-302) --305 + j*(-4) --69 + j*(175) -116 + j*(18) -30 + j*(-141) --93 + j*(-135) --163 + j*(-81) --216 + j*(28) --139 + j*(171) -18 + j*(165) -49 + j*(78) -57 + j*(83) -155 + j*(21) -103 + j*(-164) --122 + j*(-168) --175 + j*(40) --28 + j*(109) -23 + j*(23) --23 + j*(6) --10 + j*(32) -2 + j*(1) --35 + j*(-1) --23 + j*(35) -13 + j*(-4) --66 + j*(-68) --210 + j*(28) --175 + j*(274) -111 + j*(379) -349 + j*(170) -293 + j*(-82) -161 + j*(-128) -151 + j*(-157) -40 + j*(-276) --187 + j*(-195) --172 + j*(47) -14 + j*(54) --13 + j*(-79) --132 + j*(-13) --64 + j*(110) -35 + j*(85) -52 + j*(49) -99 + j*(15) -79 + j*(-91) --39 + j*(-89) --27 + j*(5) -39 + j*(-52) --76 + j*(-105) --136 + j*(44) -11 + j*(106) -51 + j*(-4) --18 + j*(1) -37 + j*(23) -4 + j*(-74) --138 + j*(35) -53 + j*(249) -366 + j*(14) -157 + j*(-379) --248 + j*(-250) --188 + j*(83) -41 + j*(38) --22 + j*(-115) --141 + j*(-55) --129 + j*(31) --105 + j*(80) --28 + j*(122) -49 + j*(49) --32 + j*(-14) --62 + j*(99) -91 + j*(110) -94 + j*(-57) --52 + j*(-32) -41 + j*(77) -134 + j*(-120) --168 + j*(-247) --377 + j*(124) --13 + j*(419) -333 + j*(126) -125 + j*(-203) --144 + j*(-54) --21 + j*(157) -153 + j*(50) -77 + j*(-89) --10 + j*(-42) -33 + j*(-24) --8 + j*(-95) --121 + j*(-30) --54 + j*(96) -50 + j*(21) --81 + j*(-54) --167 + j*(165) -110 + j*(319) -340 + j*(62) -156 + j*(-168) -14 + j*(-24) -199 + j*(27) -245 + j*(-236) --26 + j*(-341) --163 + j*(-165) --98 + j*(-92) --140 + j*(-118) --202 + j*(-4) --97 + j*(97) --11 + j*(29) --64 + j*(-8) --75 + j*(61) -6 + j*(84) -62 + j*(32) -72 + j*(-46) -13 + j*(-127) --112 + j*(-111) --132 + j*(13) --25 + j*(25) --56 + j*(-96) --250 + j*(-49) --264 + j*(226) -14 + j*(361) -247 + j*(173) -189 + j*(-72) -2 + j*(-122) --89 + j*(-29) --75 + j*(69) --3 + j*(126) -95 + j*(119) -141 + j*(39) -118 + j*(-20) -115 + j*(-37) -116 + j*(-103) -31 + j*(-166) --64 + j*(-118) --65 + j*(-54) --66 + j*(-45) --90 + j*(16) -6 + j*(77) -94 + j*(-42) --61 + j*(-146) --194 + j*(41) -13 + j*(211) -212 + j*(1) -8 + j*(-216) --228 + j*(-27) --75 + j*(230) -174 + j*(141) -160 + j*(-45) -83 + j*(-62) -115 + j*(-94) -39 + j*(-226) --177 + j*(-192) --229 + j*(41) --44 + j*(156) -86 + j*(37) -6 + j*(-76) --101 + j*(-11) --45 + j*(110) -105 + j*(72) -92 + j*(-110) --130 + j*(-128) --197 + j*(137) -96 + j*(279) -316 + j*(0) -93 + j*(-269) --172 + j*(-113) --61 + j*(115) -125 + j*(30) -73 + j*(-115) -4 + j*(-102) -11 + j*(-150) --149 + j*(-238) --384 + j*(-59) --305 + j*(295) -54 + j*(376) -254 + j*(119) -124 + j*(-99) --45 + j*(-50) --22 + j*(57) -33 + j*(26) --25 + j*(24) -21 + j*(144) -226 + j*(79) -194 + j*(-200) --114 + j*(-233) --198 + j*(49) -19 + j*(156) -126 + j*(13) -56 + j*(-76) --11 + j*(-73) --66 + j*(-25) --28 + j*(86) -134 + j*(58) -122 + j*(-135) --61 + j*(-136) --48 + j*(8) -57 + j*(-56) --45 + j*(-141) --107 + j*(-39) --30 + j*(-52) --159 + j*(-131) --292 + j*(89) --57 + j*(279) -117 + j*(89) --38 + j*(10) -1 + j*(186) -231 + j*(69) -86 + j*(-197) --174 + j*(-53) --38 + j*(173) -136 + j*(46) -21 + j*(-68) --37 + j*(43) -69 + j*(60) -68 + j*(-39) --21 + j*(-29) --25 + j*(62) -76 + j*(116) -218 + j*(29) -185 + j*(-206) --100 + j*(-251) --214 + j*(39) -54 + j*(186) -209 + j*(-40) -37 + j*(-188) --83 + j*(-73) --18 + j*(6) -35 + j*(-20) -56 + j*(-64) -25 + j*(-142) --98 + j*(-144) --122 + j*(-19) --17 + j*(-11) --58 + j*(-113) --182 + j*(-39) --112 + j*(105) -23 + j*(50) --20 + j*(-59) --103 + j*(-37) --104 + j*(3) --135 + j*(6) --189 + j*(83) --144 + j*(216) -12 + j*(267) -136 + j*(172) -117 + j*(60) -77 + j*(79) -180 + j*(68) -186 + j*(-144) --102 + j*(-214) --239 + j*(102) -61 + j*(281) -254 + j*(25) -56 + j*(-141) --49 + j*(6) -57 + j*(30) --7 + j*(-59) --101 + j*(93) -103 + j*(225) -279 + j*(25) -134 + j*(-156) -2 + j*(-59) -90 + j*(11) -130 + j*(-89) -39 + j*(-122) -33 + j*(-61) -78 + j*(-105) --21 + j*(-170) --120 + j*(-28) -64 + j*(127) -313 + j*(-81) -153 + j*(-427) --210 + j*(-384) --231 + j*(-131) --118 + j*(-202) --387 + j*(-298) --633 + j*(100) --279 + j*(514) -172 + j*(310) -67 + j*(-50) --197 + j*(56) --66 + j*(297) -193 + j*(192) -164 + j*(-54) --28 + j*(-98) --116 + j*(18) --81 + j*(117) --19 + j*(151) -37 + j*(168) -129 + j*(162) -209 + j*(63) -163 + j*(-70) -45 + j*(-78) -25 + j*(6) -100 + j*(17) -131 + j*(-62) -88 + j*(-138) --5 + j*(-174) --111 + j*(-132) --146 + j*(-30) --123 + j*(44) --94 + j*(106) -11 + j*(177) -171 + j*(91) -123 + j*(-115) --89 + j*(-86) --54 + j*(130) -180 + j*(79) -123 + j*(-181) --157 + j*(-134) --135 + j*(154) -141 + j*(170) -193 + j*(-69) -15 + j*(-131) --30 + j*(-1) -87 + j*(23) -130 + j*(-98) -33 + j*(-192) --98 + j*(-163) --141 + j*(-40) --41 + j*(35) -35 + j*(-76) --122 + j*(-187) --322 + j*(-10) --206 + j*(290) -116 + j*(298) -231 + j*(49) -106 + j*(-91) -16 + j*(-54) -35 + j*(-28) -39 + j*(-62) -7 + j*(-80) --8 + j*(-82) --33 + j*(-113) --124 + j*(-127) --225 + j*(-24) --181 + j*(148) --6 + j*(187) -78 + j*(68) -18 + j*(-5) --16 + j*(27) -11 + j*(34) -21 + j*(15) -33 + j*(-19) --19 + j*(-102) --199 + j*(-66) --223 + j*(192) -48 + j*(288) -165 + j*(59) --33 + j*(-6) --26 + j*(218) -255 + j*(191) -272 + j*(-114) -8 + j*(-186) --96 + j*(-7) --14 + j*(115) -115 + j*(137) -253 + j*(25) -185 + j*(-202) --76 + j*(-175) --47 + j*(91) -243 + j*(33) -178 + j*(-313) --200 + j*(-301) --272 + j*(54) --1 + j*(194) -169 + j*(40) -136 + j*(-121) -37 + j*(-179) --43 + j*(-160) --63 + j*(-138) --114 + j*(-163) --235 + j*(-103) --231 + j*(80) --65 + j*(129) --11 + j*(6) --116 + j*(-33) --173 + j*(54) --153 + j*(148) --80 + j*(243) -95 + j*(272) -233 + j*(119) -171 + j*(-49) -55 + j*(-51) -62 + j*(1) -98 + j*(-42) -52 + j*(-112) --40 + j*(-102) --72 + j*(-16) -1 + j*(43) -81 + j*(-20) -53 + j*(-125) --43 + j*(-179) --188 + j*(-168) --325 + j*(2) --218 + j*(263) -74 + j*(243) -76 + j*(-13) --163 + j*(36) --66 + j*(303) -223 + j*(214) -158 + j*(-27) -11 + j*(62) -166 + j*(144) -234 + j*(-49) -67 + j*(-89) -112 + j*(40) -257 + j*(-106) -83 + j*(-316) --161 + j*(-204) --150 + j*(-12) --67 + j*(54) -35 + j*(88) -170 + j*(-28) -55 + j*(-238) --200 + j*(-151) --151 + j*(99) -42 + j*(74) -9 + j*(-31) --1 + j*(45) -143 + j*(-13) -63 + j*(-231) --192 + j*(-179) --185 + j*(47) --30 + j*(47) --66 + j*(-51) --162 + j*(28) --84 + j*(158) -79 + j*(127) -111 + j*(-55) --77 + j*(-161) --276 + j*(13) --178 + j*(303) -132 + j*(349) -320 + j*(135) -297 + j*(-108) -119 + j*(-267) --125 + j*(-216) --168 + j*(18) -16 + j*(81) -48 + j*(-74) --92 + j*(-81) --94 + j*(18) --81 + j*(-3) --179 + j*(80) --57 + j*(281) -202 + j*(188) -150 + j*(-26) -40 + j*(47) -203 + j*(78) -226 + j*(-163) -0 + j*(-209) --13 + j*(-86) -6 + j*(-194) --262 + j*(-181) --286 + j*(189) -80 + j*(265) -151 + j*(-21) --35 + j*(-16) -78 + j*(108) -181 + j*(-91) --48 + j*(-185) --113 + j*(24) -58 + j*(37) -21 + j*(-93) --57 + j*(-22) -38 + j*(-23) --54 + j*(-161) --253 + j*(-11) --105 + j*(243) -149 + j*(144) -117 + j*(-54) -15 + j*(-83) --57 + j*(-91) --180 + j*(6) --98 + j*(235) -189 + j*(204) -222 + j*(-64) -36 + j*(-125) --2 + j*(-39) -12 + j*(-47) --20 + j*(-14) -54 + j*(13) -81 + j*(-112) --78 + j*(-156) --151 + j*(-22) --98 + j*(49) --86 + j*(112) -76 + j*(211) -308 + j*(4) -122 + j*(-337) --262 + j*(-223) --233 + j*(119) -6 + j*(144) -40 + j*(33) -45 + j*(11) -43 + j*(-90) --130 + j*(-105) --162 + j*(110) -53 + j*(146) -67 + j*(-40) --78 + j*(-10) --3 + j*(91) -42 + j*(-25) --122 + j*(-4) --47 + j*(221) -228 + j*(124) -138 + j*(-163) --124 + j*(-83) --40 + j*(128) -112 + j*(25) --30 + j*(-65) --81 + j*(145) -210 + j*(213) -359 + j*(-129) -35 + j*(-382) --292 + j*(-139) --144 + j*(200) -153 + j*(124) -97 + j*(-101) --52 + j*(-10) -112 + j*(100) -239 + j*(-129) -11 + j*(-296) --152 + j*(-137) --54 + j*(-61) --98 + j*(-168) --269 + j*(-66) --192 + j*(139) --30 + j*(98) --91 + j*(12) --161 + j*(124) --47 + j*(248) -115 + j*(233) -236 + j*(119) -250 + j*(-72) -95 + j*(-197) --52 + j*(-136) --57 + j*(-49) --47 + j*(-37) --54 + j*(-12) --31 + j*(-16) --93 + j*(-37) --151 + j*(93) -11 + j*(206) -153 + j*(60) -35 + j*(-54) --14 + j*(54) -110 + j*(35) -32 + j*(-99) --103 + j*(47) -114 + j*(197) -316 + j*(-71) -65 + j*(-332) --214 + j*(-156) --134 + j*(71) --4 + j*(54) -1 + j*(30) -66 + j*(43) -121 + j*(-80) --9 + j*(-190) --156 + j*(-113) --150 + j*(11) --104 + j*(44) --106 + j*(69) --71 + j*(145) -52 + j*(167) -144 + j*(62) -97 + j*(-61) --7 + j*(-66) --28 + j*(-11) --20 + j*(-7) --63 + j*(14) --44 + j*(110) -88 + j*(124) -147 + j*(-8) -36 + j*(-94) --58 + j*(1) -39 + j*(115) -204 + j*(23) -161 + j*(-202) --83 + j*(-239) --188 + j*(-33) --38 + j*(81) -49 + j*(-44) --83 + j*(-132) --227 + j*(-7) --192 + j*(210) -33 + j*(340) -315 + j*(206) -324 + j*(-126) -49 + j*(-216) --6 + j*(-18) -190 + j*(-70) -64 + j*(-332) --242 + j*(-202) --119 + j*(66) -68 + j*(-121) --240 + j*(-272) --431 + j*(117) --62 + j*(359) -168 + j*(81) --14 + j*(-62) --42 + j*(56) -35 + j*(-28) --143 + j*(-83) --199 + j*(154) -36 + j*(207) -38 + j*(9) --150 + j*(108) -25 + j*(344) -317 + j*(180) -221 + j*(-98) -23 + j*(-40) -105 + j*(94) -245 + j*(-13) -183 + j*(-194) -4 + j*(-231) --112 + j*(-112) --64 + j*(18) -39 + j*(7) -29 + j*(-66) --8 + j*(-44) -40 + j*(-46) -14 + j*(-140) --119 + j*(-122) --127 + j*(6) --47 + j*(11) --90 + j*(-26) --123 + j*(74) --8 + j*(132) -60 + j*(39) --11 + j*(-6) --38 + j*(69) -47 + j*(123) -156 + j*(77) -216 + j*(-64) -124 + j*(-233) --90 + j*(-257) --214 + j*(-104) --177 + j*(40) --98 + j*(95) --26 + j*(106) -40 + j*(76) -68 + j*(6) -35 + j*(-67) --59 + j*(-93) --153 + j*(0) --78 + j*(149) -103 + j*(101) -69 + j*(-101) --152 + j*(-82) --163 + j*(154) -59 + j*(207) -144 + j*(28) -11 + j*(-62) --85 + j*(35) --25 + j*(155) -107 + j*(158) -172 + j*(62) -152 + j*(-12) -137 + j*(-38) -126 + j*(-89) -62 + j*(-109) -65 + j*(-64) -127 + j*(-144) --11 + j*(-286) --241 + j*(-156) --163 + j*(96) -54 + j*(46) --8 + j*(-119) --135 + j*(-46) --76 + j*(45) --47 + j*(12) --54 + j*(60) -71 + j*(45) -36 + j*(-161) --245 + j*(-125) --243 + j*(197) -57 + j*(221) -52 + j*(-16) --157 + j*(70) --7 + j*(316) -300 + j*(180) -240 + j*(-146) --49 + j*(-164) --121 + j*(78) -91 + j*(207) -287 + j*(41) -203 + j*(-204) --25 + j*(-200) --50 + j*(-33) -74 + j*(-29) -61 + j*(-146) --47 + j*(-156) --89 + j*(-97) --93 + j*(-52) --59 + j*(-19) --25 + j*(-72) --133 + j*(-123) --226 + j*(28) --69 + j*(151) -38 + j*(-12) --158 + j*(-95) --256 + j*(132) --58 + j*(262) -54 + j*(157) -24 + j*(139) -112 + j*(168) -187 + j*(37) -86 + j*(-59) -16 + j*(0) -59 + j*(20) -46 + j*(-21) --2 + j*(8) -18 + j*(72) -103 + j*(110) -242 + j*(49) -283 + j*(-177) -63 + j*(-349) --171 + j*(-238) --180 + j*(-73) --181 + j*(-31) --218 + j*(127) -13 + j*(308) -317 + j*(100) -180 + j*(-249) --138 + j*(-177) --78 + j*(81) -146 + j*(-2) -57 + j*(-236) --176 + j*(-192) --194 + j*(-18) --125 + j*(-6) --196 + j*(-15) --239 + j*(140) --93 + j*(263) -40 + j*(199) -26 + j*(161) -98 + j*(230) -284 + j*(135) -255 + j*(-117) -28 + j*(-158) --29 + j*(-4) -69 + j*(37) -98 + j*(-4) -141 + j*(-21) -175 + j*(-158) --8 + j*(-275) --180 + j*(-100) --18 + j*(64) -117 + j*(-118) --94 + j*(-255) --248 + j*(-61) --112 + j*(74) --43 + j*(-29) --158 + j*(-42) --182 + j*(93) --77 + j*(161) -21 + j*(132) -57 + j*(35) --44 + j*(-43) --165 + j*(81) --31 + j*(267) -203 + j*(157) -128 + j*(-79) --87 + j*(-9) --4 + j*(209) -245 + j*(149) -262 + j*(-107) -58 + j*(-215) --103 + j*(-107) --89 + j*(53) -44 + j*(110) -147 + j*(25) -136 + j*(-93) -44 + j*(-163) --94 + j*(-143) --162 + j*(35) -33 + j*(192) -276 + j*(1) -118 + j*(-319) --238 + j*(-221) --201 + j*(113) -76 + j*(107) -74 + j*(-97) --54 + j*(-91) --29 + j*(-59) --99 + j*(-143) --282 + j*(-12) --161 + j*(262) -140 + j*(199) -129 + j*(-60) --64 + j*(-62) --53 + j*(68) -25 + j*(51) -6 + j*(24) -28 + j*(52) -80 + j*(-8) -14 + j*(-88) --90 + j*(-59) --140 + j*(35) --114 + j*(186) -98 + j*(286) -330 + j*(91) -204 + j*(-202) --58 + j*(-122) -52 + j*(80) -236 + j*(-100) -20 + j*(-310) --190 + j*(-115) --12 + j*(36) -76 + j*(-176) --187 + j*(-270) --344 + j*(-37) --238 + j*(147) --126 + j*(180) --33 + j*(186) -35 + j*(103) --52 + j*(49) --85 + j*(202) -136 + j*(264) -256 + j*(45) -103 + j*(-90) -21 + j*(-9) -54 + j*(-2) --6 + j*(-4) -35 + j*(121) -237 + j*(49) -168 + j*(-221) --132 + j*(-182) --128 + j*(100) -96 + j*(123) -135 + j*(-8) -127 + j*(-30) -165 + j*(-132) -10 + j*(-247) --133 + j*(-87) -42 + j*(19) -100 + j*(-223) --222 + j*(-286) --333 + j*(62) --33 + j*(204) -95 + j*(-21) --64 + j*(-117) --130 + j*(-28) --133 + j*(-2) --188 + j*(76) --101 + j*(226) -95 + j*(206) -155 + j*(47) -94 + j*(-64) --34 + j*(-110) --178 + j*(15) --74 + j*(246) -210 + j*(184) -187 + j*(-86) --14 + j*(-54) -100 + j*(81) -223 + j*(-134) --47 + j*(-290) --216 + j*(-41) --10 + j*(69) --2 + j*(-136) --267 + j*(-77) --235 + j*(247) -64 + j*(313) -211 + j*(148) -238 + j*(6) -191 + j*(-171) --45 + j*(-252) --218 + j*(-37) --59 + j*(169) -144 + j*(66) -88 + j*(-122) --86 + j*(-115) --136 + j*(40) --5 + j*(144) -148 + j*(40) -75 + j*(-150) --138 + j*(-115) --154 + j*(91) --1 + j*(159) -87 + j*(103) -144 + j*(42) -158 + j*(-103) --23 + j*(-199) --171 + j*(-38) --54 + j*(110) -37 + j*(25) --58 + j*(23) -9 + j*(170) -218 + j*(90) -172 + j*(-133) --3 + j*(-113) -45 + j*(-8) -119 + j*(-112) --10 + j*(-196) --89 + j*(-106) --42 + j*(-93) --127 + j*(-153) --262 + j*(-16) --144 + j*(182) -47 + j*(115) --1 + j*(-23) --86 + j*(62) -46 + j*(127) -110 + j*(-31) --53 + j*(-82) --69 + j*(88) -113 + j*(64) -59 + j*(-134) --136 + j*(-60) --41 + j*(107) -82 + j*(-21) --89 + j*(-90) --97 + j*(122) -169 + j*(59) -45 + j*(-286) --397 + j*(-161) --355 + j*(334) -84 + j*(410) -231 + j*(128) -119 + j*(5) -63 + j*(3) -4 + j*(25) -30 + j*(139) -221 + j*(116) -240 + j*(-124) -23 + j*(-187) --40 + j*(-53) -13 + j*(-55) --84 + j*(-57) --74 + j*(125) -165 + j*(130) -197 + j*(-127) --37 + j*(-181) --86 + j*(2) -45 + j*(20) -16 + j*(-74) --71 + j*(1) -35 + j*(109) -179 + j*(11) -139 + j*(-147) -26 + j*(-174) --8 + j*(-152) --52 + j*(-191) --188 + j*(-172) --266 + j*(3) --136 + j*(168) -52 + j*(132) -100 + j*(-23) -17 + j*(-127) --110 + j*(-131) --202 + j*(-24) --151 + j*(117) --20 + j*(118) --13 + j*(30) --76 + j*(63) --2 + j*(139) -105 + j*(52) -33 + j*(-74) --95 + j*(-33) --92 + j*(82) --8 + j*(115) -42 + j*(70) -19 + j*(27) --23 + j*(67) -59 + j*(145) -216 + j*(42) -144 + j*(-204) --153 + j*(-209) --245 + j*(70) --40 + j*(204) -59 + j*(79) --44 + j*(63) -1 + j*(219) -226 + j*(186) -257 + j*(-53) -64 + j*(-124) -5 + j*(14) -122 + j*(37) -124 + j*(-71) -35 + j*(-55) -83 + j*(21) -177 + j*(-45) -146 + j*(-151) -92 + j*(-190) -26 + j*(-250) --139 + j*(-231) --185 + j*(-25) -24 + j*(56) -122 + j*(-159) --81 + j*(-301) --264 + j*(-180) --276 + j*(-36) --257 + j*(64) --177 + j*(170) --37 + j*(166) --4 + j*(84) --8 + j*(76) -38 + j*(30) --32 + j*(-66) --163 + j*(13) --101 + j*(153) -1 + j*(117) --42 + j*(90) --12 + j*(180) -119 + j*(151) -118 + j*(46) -96 + j*(48) -146 + j*(-9) -49 + j*(-115) --74 + j*(-1) -65 + j*(105) -148 + j*(-71) --60 + j*(-138) --116 + j*(88) -109 + j*(135) -158 + j*(-69) -0 + j*(-125) --55 + j*(-34) --37 + j*(9) --11 + j*(54) -79 + j*(37) -63 + j*(-92) --106 + j*(-74) --110 + j*(134) -105 + j*(196) -244 + j*(34) -192 + j*(-152) -17 + j*(-219) --125 + j*(-83) --1 + j*(95) -216 + j*(-44) -77 + j*(-322) --231 + j*(-233) --198 + j*(36) --13 + j*(4) --98 + j*(-134) --258 + j*(-17) --184 + j*(182) -8 + j*(197) -91 + j*(61) -1 + j*(-35) --86 + j*(46) -16 + j*(127) -89 + j*(-1) --80 + j*(-47) --95 + j*(187) -206 + j*(194) -231 + j*(-133) --62 + j*(-153) --21 + j*(76) -164 + j*(-67) --66 + j*(-256) --270 + j*(-5) --62 + j*(169) -6 + j*(22) --118 + j*(103) -91 + j*(258) -290 + j*(-17) -15 + j*(-226) --156 + j*(23) -66 + j*(129) -97 + j*(-69) --72 + j*(-26) -34 + j*(121) -175 + j*(-28) -25 + j*(-163) --91 + j*(-52) --42 + j*(16) --49 + j*(22) --19 + j*(124) -164 + j*(124) -243 + j*(-84) -98 + j*(-250) --100 + j*(-234) --218 + j*(-77) --147 + j*(123) -78 + j*(139) -161 + j*(-71) -4 + j*(-197) --129 + j*(-128) --143 + j*(-45) --141 + j*(2) --122 + j*(45) --107 + j*(54) --117 + j*(101) --40 + j*(161) -40 + j*(84) --67 + j*(37) --97 + j*(231) -188 + j*(313) -370 + j*(17) -158 + j*(-226) --66 + j*(-129) --54 + j*(23) -35 + j*(68) -139 + j*(27) -158 + j*(-143) --45 + j*(-235) --185 + j*(-54) --51 + j*(61) --35 + j*(-49) --178 + j*(45) --4 + j*(259) -267 + j*(54) -59 + j*(-241) --228 + j*(-37) --34 + j*(224) -180 + j*(54) -35 + j*(-87) --25 + j*(50) -119 + j*(49) -84 + j*(-80) -0 + j*(-6) -139 + j*(39) -206 + j*(-162) -13 + j*(-283) --124 + j*(-184) --116 + j*(-117) --155 + j*(-119) --226 + j*(-56) --247 + j*(66) --173 + j*(209) -42 + j*(250) -177 + j*(32) --29 + j*(-141) --209 + j*(83) -45 + j*(274) -258 + j*(11) -16 + j*(-204) --165 + j*(-1) --2 + j*(117) -32 + j*(-23) --111 + j*(28) --8 + j*(192) -165 + j*(91) -99 + j*(-37) -73 + j*(5) -147 + j*(-90) --31 + j*(-238) --258 + j*(-49) --117 + j*(214) -118 + j*(139) -89 + j*(-19) -11 + j*(0) -40 + j*(21) -35 + j*(-11) -9 + j*(13) -49 + j*(36) -94 + j*(3) -107 + j*(-69) -24 + j*(-164) --161 + j*(-100) --141 + j*(158) -157 + j*(201) -267 + j*(-76) -83 + j*(-209) -10 + j*(-151) --16 + j*(-212) --202 + j*(-191) --211 + j*(35) --29 + j*(13) --168 + j*(-146) --388 + j*(119) --94 + j*(441) -273 + j*(221) -144 + j*(-82) --36 + j*(16) -87 + j*(100) -141 + j*(-43) -18 + j*(-96) --24 + j*(-37) --25 + j*(-23) --53 + j*(13) --23 + j*(74) -40 + j*(106) -163 + j*(103) -291 + j*(-91) -100 + j*(-375) --272 + j*(-255) --221 + j*(100) -53 + j*(44) --82 + j*(-169) --295 + j*(35) --92 + j*(264) -97 + j*(131) -34 + j*(59) -103 + j*(104) -171 + j*(-62) --25 + j*(-145) --67 + j*(46) -138 + j*(-2) -1 + j*(-266) --345 + j*(-102) --222 + j*(293) -151 + j*(245) -151 + j*(-49) --62 + j*(-60) --69 + j*(107) -81 + j*(129) -144 + j*(-4) -32 + j*(-121) --141 + j*(-47) --134 + j*(176) -87 + j*(270) -281 + j*(137) -303 + j*(-72) -185 + j*(-235) --19 + j*(-260) --150 + j*(-108) --71 + j*(45) -59 + j*(11) -47 + j*(-105) --69 + j*(-129) --163 + j*(-31) --121 + j*(141) -97 + j*(195) -257 + j*(-18) -95 + j*(-258) --180 + j*(-167) --146 + j*(113) -137 + j*(120) -197 + j*(-177) --105 + j*(-314) --317 + j*(-47) --110 + j*(209) -154 + j*(55) -45 + j*(-206) --199 + j*(-161) --227 + j*(14) --176 + j*(76) --161 + j*(139) --66 + j*(207) -28 + j*(161) -32 + j*(127) -88 + j*(130) -134 + j*(21) -21 + j*(-32) -13 + j*(87) -168 + j*(25) -63 + j*(-192) --204 + j*(-83) --122 + j*(182) -84 + j*(126) -18 + j*(18) --4 + j*(131) -150 + j*(105) -93 + j*(-37) --3 + j*(91) -233 + j*(173) -367 + j*(-139) -78 + j*(-336) --112 + j*(-143) --4 + j*(-45) --9 + j*(-131) --103 + j*(-71) --32 + j*(-3) --30 + j*(-91) --170 + j*(-27) --76 + j*(189) -197 + j*(115) -184 + j*(-183) --89 + j*(-236) --194 + j*(-35) --69 + j*(81) -33 + j*(7) --21 + j*(-98) --161 + j*(-71) --204 + j*(107) --37 + j*(241) -161 + j*(144) -149 + j*(-46) -23 + j*(-83) --8 + j*(-36) --11 + j*(-44) --68 + j*(-16) --21 + j*(86) -132 + j*(37) -116 + j*(-173) --110 + j*(-238) --264 + j*(-83) --255 + j*(90) --177 + j*(215) --18 + j*(296) -179 + j*(214) -214 + j*(6) -68 + j*(-100) --61 + j*(-35) --76 + j*(94) -28 + j*(204) -221 + j*(187) -339 + j*(-5) -269 + j*(-218) -93 + j*(-317) --90 + j*(-290) --208 + j*(-153) --174 + j*(-4) --92 + j*(18) --100 + j*(8) --82 + j*(83) -41 + j*(72) -41 + j*(-76) --122 + j*(-94) --178 + j*(50) --107 + j*(134) --55 + j*(170) -46 + j*(211) -180 + j*(128) -154 + j*(-30) -33 + j*(-28) -62 + j*(72) -199 + j*(27) -215 + j*(-164) -37 + j*(-307) --204 + j*(-242) --288 + j*(-9) --171 + j*(158) --47 + j*(177) -31 + j*(182) -157 + j*(148) -211 + j*(-5) -117 + j*(-101) -71 + j*(-81) -66 + j*(-141) --81 + j*(-169) --163 + j*(18) -25 + j*(127) -137 + j*(-39) -8 + j*(-131) --37 + j*(-42) -28 + j*(-64) --48 + j*(-138) --127 + j*(-55) --64 + j*(-16) --105 + j*(-90) --244 + j*(19) --136 + j*(239) -115 + j*(183) -109 + j*(-37) --54 + j*(-30) --6 + j*(98) -125 + j*(0) --4 + j*(-169) --224 + j*(-39) --127 + j*(221) -142 + j*(183) -163 + j*(-52) -3 + j*(-110) --57 + j*(-47) --82 + j*(-33) --137 + j*(42) --74 + j*(148) -19 + j*(119) --8 + j*(95) -24 + j*(173) -148 + j*(144) -152 + j*(57) -177 + j*(71) -301 + j*(-57) -147 + j*(-323) --212 + j*(-216) --170 + j*(158) -158 + j*(166) -208 + j*(-74) -96 + j*(-134) -68 + j*(-169) --72 + j*(-209) --172 + j*(-21) -32 + j*(85) -112 + j*(-146) --152 + j*(-204) --201 + j*(76) -69 + j*(110) -78 + j*(-144) --173 + j*(-148) --206 + j*(94) -5 + j*(179) -146 + j*(25) -59 + j*(-169) --175 + j*(-153) --226 + j*(95) -10 + j*(196) -125 + j*(-16) --63 + j*(-127) --161 + j*(30) --50 + j*(101) --45 + j*(33) --116 + j*(107) -6 + j*(240) -213 + j*(154) -223 + j*(-80) -44 + j*(-195) --124 + j*(-118) --154 + j*(23) --95 + j*(109) --25 + j*(144) -65 + j*(130) -93 + j*(28) --23 + j*(3) --41 + j*(175) -191 + j*(228) -316 + j*(4) -185 + j*(-139) -129 + j*(-107) -139 + j*(-197) --44 + j*(-263) --156 + j*(-78) --8 + j*(11) -12 + j*(-128) --142 + j*(-95) --98 + j*(57) -14 + j*(12) --44 + j*(-38) --41 + j*(38) -37 + j*(-1) --17 + j*(-58) --8 + j*(2) -69 + j*(-117) --173 + j*(-255) --416 + j*(61) --106 + j*(380) -202 + j*(123) --37 + j*(-95) --159 + j*(194) -202 + j*(280) -305 + j*(-110) --48 + j*(-237) --175 + j*(40) -17 + j*(151) -99 + j*(49) -89 + j*(11) -108 + j*(-40) -42 + j*(-106) --22 + j*(-56) -32 + j*(-42) --19 + j*(-139) --181 + j*(-54) --98 + j*(169) -161 + j*(101) -119 + j*(-177) --168 + j*(-175) --224 + j*(81) --42 + j*(186) -69 + j*(107) -79 + j*(40) -71 + j*(-13) -8 + j*(-39) --18 + j*(30) -74 + j*(40) -71 + j*(-88) --93 + j*(-84) --103 + j*(117) -117 + j*(165) -234 + j*(-37) -115 + j*(-219) --88 + j*(-229) --228 + j*(-66) --147 + j*(160) -113 + j*(151) -153 + j*(-106) --80 + j*(-168) --131 + j*(13) --11 + j*(6) --115 + j*(-80) --220 + j*(122) -30 + j*(283) -231 + j*(51) -51 + j*(-148) --115 + j*(-27) --54 + j*(92) -1 + j*(101) -71 + j*(133) -204 + j*(47) -149 + j*(-150) --49 + j*(-141) --57 + j*(23) -74 + j*(31) -106 + j*(-79) -54 + j*(-171) --86 + j*(-245) --306 + j*(-141) --325 + j*(156) --70 + j*(288) -83 + j*(156) -46 + j*(88) -86 + j*(115) -158 + j*(23) -77 + j*(-86) --24 + j*(-36) -1 + j*(38) -54 + j*(31) -68 + j*(4) -74 + j*(-21) -71 + j*(-45) -72 + j*(-72) -45 + j*(-136) --73 + j*(-156) --146 + j*(-31) --47 + j*(54) -6 + j*(-28) --95 + j*(-40) --88 + j*(93) -56 + j*(94) -69 + j*(-23) -12 + j*(-25) -54 + j*(-30) -16 + j*(-139) --152 + j*(-108) --157 + j*(76) --4 + j*(113) -44 + j*(16) -5 + j*(-21) --18 + j*(-37) --75 + j*(-35) --98 + j*(37) --44 + j*(64) --59 + j*(38) --85 + j*(127) -62 + j*(199) -191 + j*(50) -99 + j*(-103) --20 + j*(-98) --95 + j*(-77) --221 + j*(28) --174 + j*(302) -161 + j*(393) -378 + j*(131) -269 + j*(-100) -143 + j*(-91) -175 + j*(-71) -202 + j*(-180) -83 + j*(-320) --159 + j*(-292) --243 + j*(-25) -6 + j*(103) -125 + j*(-158) --182 + j*(-278) --330 + j*(53) --28 + j*(209) -87 + j*(-44) --133 + j*(-98) --148 + j*(98) --8 + j*(100) --25 + j*(47) -15 + j*(103) -116 + j*(-4) --33 + j*(-134) --166 + j*(30) --9 + j*(145) -65 + j*(6) --54 + j*(-18) --39 + j*(66) --13 + j*(16) --127 + j*(62) --58 + j*(260) -182 + j*(251) -255 + j*(86) -262 + j*(12) -310 + j*(-136) -165 + j*(-339) --88 + j*(-323) --206 + j*(-184) --265 + j*(-32) --186 + j*(199) -124 + j*(227) -233 + j*(-72) -2 + j*(-201) --70 + j*(-66) --18 + j*(-109) --199 + j*(-134) --247 + j*(142) -52 + j*(219) -122 + j*(-47) --98 + j*(-73) --71 + j*(100) -48 + j*(25) --83 + j*(-39) --117 + j*(148) -96 + j*(191) -163 + j*(14) -69 + j*(-51) -52 + j*(-48) --1 + j*(-100) --112 + j*(-35) --72 + j*(105) -53 + j*(110) -95 + j*(47) -127 + j*(4) -151 + j*(-115) -1 + j*(-254) --248 + j*(-164) --279 + j*(143) --1 + j*(298) -228 + j*(104) -124 + j*(-119) --37 + j*(-70) -9 + j*(3) --1 + j*(-85) --151 + j*(-22) --82 + j*(185) -129 + j*(152) -133 + j*(8) -112 + j*(22) -209 + j*(-59) -104 + j*(-248) --107 + j*(-182) --71 + j*(-43) --45 + j*(-108) --172 + j*(-52) --74 + j*(115) -83 + j*(-25) --111 + j*(-149) --212 + j*(94) -50 + j*(164) -59 + j*(-96) --214 + j*(-33) --108 + j*(274) -221 + j*(184) -180 + j*(-109) --30 + j*(-104) --18 + j*(21) -74 + j*(-22) -15 + j*(-140) --161 + j*(-123) --222 + j*(91) --16 + j*(219) -119 + j*(31) --93 + j*(-53) --136 + j*(249) -267 + j*(321) -422 + j*(-106) -83 + j*(-326) --103 + j*(-133) --19 + j*(-66) --76 + j*(-122) --156 + j*(-10) --61 + j*(81) -4 + j*(31) --7 + j*(6) --9 + j*(-18) --76 + j*(-28) --103 + j*(77) -8 + j*(109) --6 + j*(26) --76 + j*(143) -158 + j*(265) -379 + j*(-24) -124 + j*(-326) --173 + j*(-161) --82 + j*(57) -29 + j*(-19) --76 + j*(-59) --96 + j*(74) -27 + j*(110) -71 + j*(33) -47 + j*(18) -88 + j*(33) -153 + j*(-46) -93 + j*(-183) --85 + j*(-192) --160 + j*(-37) --65 + j*(51) --23 + j*(8) --49 + j*(45) -68 + j*(91) -153 + j*(-83) --45 + j*(-222) --215 + j*(-39) --76 + j*(128) -57 + j*(24) --31 + j*(-62) --94 + j*(17) --35 + j*(77) -25 + j*(60) -62 + j*(13) -48 + j*(-77) --66 + j*(-117) --169 + j*(-25) --148 + j*(110) --46 + j*(175) -66 + j*(153) -118 + j*(61) -73 + j*(-13) -18 + j*(15) -72 + j*(76) -202 + j*(-4) -170 + j*(-243) --148 + j*(-337) --383 + j*(-37) --180 + j*(274) -90 + j*(170) -14 + j*(19) --11 + j*(147) -204 + j*(98) -129 + j*(-184) --167 + j*(-109) --95 + j*(139) -38 + j*(57) --108 + j*(78) -52 + j*(354) -470 + j*(147) -305 + j*(-340) --129 + j*(-233) --25 + j*(78) -165 + j*(-70) --12 + j*(-168) --20 + j*(11) -165 + j*(-69) -56 + j*(-277) --128 + j*(-223) --151 + j*(-162) --265 + j*(-139) --330 + j*(69) --180 + j*(206) --98 + j*(208) -23 + j*(308) -322 + j*(173) -234 + j*(-235) --176 + j*(-170) --61 + j*(183) -243 + j*(-21) --40 + j*(-298) --281 + j*(18) -28 + j*(190) -106 + j*(-104) --175 + j*(-97) --111 + j*(153) -73 + j*(53) --63 + j*(-48) --102 + j*(122) -65 + j*(134) -61 + j*(25) -47 + j*(66) -148 + j*(-6) -30 + j*(-163) --146 + j*(-35) --18 + j*(112) -71 + j*(-20) --81 + j*(-45) --62 + j*(141) -157 + j*(104) -135 + j*(-134) --111 + j*(-157) --197 + j*(73) --11 + j*(230) -194 + j*(111) -134 + j*(-102) --62 + j*(-59) --3 + j*(141) -239 + j*(83) -249 + j*(-192) -9 + j*(-319) --204 + j*(-199) --226 + j*(18) --57 + j*(117) -35 + j*(-24) --144 + j*(-77) --189 + j*(177) -117 + j*(246) -204 + j*(-59) --71 + j*(-129) --109 + j*(110) -74 + j*(128) -74 + j*(46) -125 + j*(105) -293 + j*(-47) -124 + j*(-316) --171 + j*(-190) --82 + j*(49) -76 + j*(-41) --20 + j*(-145) --95 + j*(-79) --88 + j*(-45) --96 + j*(4) --4 + j*(19) --30 + j*(-130) --269 + j*(-49) --153 + j*(281) -231 + j*(144) -61 + j*(-247) --316 + j*(-23) --40 + j*(334) -289 + j*(28) --18 + j*(-257) --237 + j*(28) -10 + j*(163) -55 + j*(-52) --143 + j*(-21) --86 + j*(154) -36 + j*(115) -16 + j*(90) -100 + j*(114) -154 + j*(-57) --74 + j*(-144) --199 + j*(110) -39 + j*(281) -238 + j*(115) -183 + j*(-55) -107 + j*(-86) -57 + j*(-136) --100 + j*(-133) --185 + j*(79) -18 + j*(264) -272 + j*(126) -228 + j*(-124) -57 + j*(-138) -52 + j*(-62) -74 + j*(-105) -11 + j*(-100) -70 + j*(-62) -100 + j*(-229) --173 + j*(-303) --309 + j*(14) --11 + j*(165) -88 + j*(-107) --182 + j*(-122) --108 + j*(158) -177 + j*(-9) --81 + j*(-312) --420 + j*(10) --87 + j*(375) -267 + j*(65) --15 + j*(-252) --297 + j*(1) --99 + j*(247) -85 + j*(129) -24 + j*(45) -37 + j*(105) -133 + j*(47) -86 + j*(-66) -2 + j*(-36) -59 + j*(-3) -82 + j*(-129) --110 + j*(-208) --272 + j*(-12) --133 + j*(203) -57 + j*(128) --1 + j*(5) --67 + j*(95) -56 + j*(132) -55 + j*(2) --104 + j*(74) -21 + j*(325) -397 + j*(245) -479 + j*(-168) -187 + j*(-424) --112 + j*(-354) --223 + j*(-171) --210 + j*(-34) --180 + j*(40) --151 + j*(127) --30 + j*(218) -151 + j*(151) -162 + j*(-45) --1 + j*(-98) --57 + j*(28) -45 + j*(92) -136 + j*(23) -131 + j*(-99) -6 + j*(-171) --126 + j*(-63) --30 + j*(97) -153 + j*(-6) -38 + j*(-223) --206 + j*(-115) --122 + j*(133) -104 + j*(64) -32 + j*(-139) --155 + j*(-63) --92 + j*(118) -71 + j*(85) -76 + j*(-45) -3 + j*(-83) --49 + j*(-84) --129 + j*(-49) --145 + j*(93) -30 + j*(165) -148 + j*(-16) --26 + j*(-164) --193 + j*(-4) --58 + j*(157) -66 + j*(52) --34 + j*(-5) --21 + j*(121) -144 + j*(62) -71 + j*(-129) --114 + j*(-54) --28 + j*(91) -74 + j*(-21) --74 + j*(-101) --159 + j*(49) --75 + j*(139) --42 + j*(163) -66 + j*(264) -320 + j*(168) -315 + j*(-167) -11 + j*(-255) --103 + j*(-51) -8 + j*(26) -26 + j*(-25) -5 + j*(4) -61 + j*(14) -71 + j*(-38) -62 + j*(-42) -102 + j*(-91) -30 + j*(-209) --154 + j*(-167) --170 + j*(28) --4 + j*(84) -75 + j*(-52) --42 + j*(-158) --196 + j*(-76) --167 + j*(122) -52 + j*(160) -147 + j*(-67) --71 + j*(-224) --288 + j*(-60) --233 + j*(160) --115 + j*(214) --53 + j*(279) -156 + j*(344) -403 + j*(129) -305 + j*(-223) --13 + j*(-255) --86 + j*(-47) -35 + j*(-33) --35 + j*(-149) --202 + j*(-40) --119 + j*(170) -86 + j*(138) -84 + j*(-18) --21 + j*(-8) -10 + j*(69) -79 + j*(35) -62 + j*(-9) -64 + j*(6) -117 + j*(-38) -78 + j*(-147) --62 + j*(-166) --147 + j*(-49) --96 + j*(75) -23 + j*(88) -79 + j*(8) -55 + j*(-57) -28 + j*(-82) --13 + j*(-128) --125 + j*(-137) --226 + j*(-23) --197 + j*(148) --41 + j*(251) -158 + j*(197) -228 + j*(-18) -69 + j*(-161) --68 + j*(-64) -13 + j*(20) -49 + j*(-93) --93 + j*(-119) --125 + j*(1) --74 + j*(-6) --194 + j*(5) --200 + j*(272) -164 + j*(381) -399 + j*(35) -170 + j*(-278) --124 + j*(-202) --181 + j*(1) --99 + j*(130) -40 + j*(155) -115 + j*(48) -47 + j*(-8) -49 + j*(64) -170 + j*(11) -112 + j*(-161) --74 + j*(-132) --78 + j*(27) -31 + j*(60) -92 + j*(13) -125 + j*(-69) -62 + j*(-180) --76 + j*(-174) --123 + j*(-94) --156 + j*(-50) --170 + j*(93) -50 + j*(170) -159 + j*(-115) --197 + j*(-238) --335 + j*(179) -103 + j*(320) -206 + j*(-99) --185 + j*(-123) --128 + j*(246) -194 + j*(129) -23 + j*(-105) --100 + j*(143) -235 + j*(190) -255 + j*(-187) --83 + j*(-195) --48 + j*(43) -90 + j*(-62) --66 + j*(-126) --54 + j*(26) -61 + j*(-91) --182 + j*(-188) --292 + j*(146) -59 + j*(268) -154 + j*(-42) --104 + j*(-69) --62 + j*(144) -95 + j*(56) --24 + j*(-26) --31 + j*(132) -156 + j*(95) -112 + j*(-81) --4 + j*(-31) -79 + j*(8) -69 + j*(-118) --75 + j*(-99) --64 + j*(18) --15 + j*(8) --44 + j*(33) -38 + j*(95) -130 + j*(-11) -35 + j*(-104) --21 + j*(-25) -64 + j*(-24) -41 + j*(-137) --82 + j*(-142) --141 + j*(-64) --153 + j*(28) --67 + j*(131) -93 + j*(62) -26 + j*(-125) --173 + j*(-42) --63 + j*(158) -138 + j*(8) --60 + j*(-206) --307 + j*(6) --136 + j*(267) -69 + j*(159) --29 + j*(66) --37 + j*(230) -202 + j*(243) -265 + j*(5) -98 + j*(-65) -90 + j*(48) -213 + j*(-6) -160 + j*(-149) -56 + j*(-121) -119 + j*(-106) -91 + j*(-280) --187 + j*(-302) --305 + j*(-4) --69 + j*(175) -116 + j*(18) -30 + j*(-141) --93 + j*(-135) --163 + j*(-81) --216 + j*(28) --139 + j*(171) -18 + j*(165) -49 + j*(78) -57 + j*(83) -155 + j*(21) -103 + j*(-164) --122 + j*(-168) --175 + j*(40) --28 + j*(109) -23 + j*(23) --23 + j*(6) --10 + j*(32) -2 + j*(1) --35 + j*(-1) --23 + j*(35) -13 + j*(-4) --66 + j*(-68) --210 + j*(28) --175 + j*(274) -111 + j*(379) -349 + j*(170) -293 + j*(-82) -161 + j*(-128) -151 + j*(-157) -40 + j*(-276) --187 + j*(-195) --172 + j*(47) -14 + j*(54) --13 + j*(-79) --132 + j*(-13) --64 + j*(110) -35 + j*(85) -52 + j*(49) -99 + j*(15) -79 + j*(-91) --39 + j*(-89) --27 + j*(5) -39 + j*(-52) --76 + j*(-105) --136 + j*(44) -11 + j*(106) -51 + j*(-4) --18 + j*(1) -37 + j*(23) -4 + j*(-74) --138 + j*(35) -53 + j*(249) -366 + j*(14) -157 + j*(-379) --248 + j*(-250) --188 + j*(83) -41 + j*(38) --22 + j*(-115) --141 + j*(-55) --129 + j*(31) --105 + j*(80) --28 + j*(122) -49 + j*(49) --32 + j*(-14) --62 + j*(99) -91 + j*(110) -94 + j*(-57) --52 + j*(-32) -41 + j*(77) -134 + j*(-120) --168 + j*(-247) --377 + j*(124) --13 + j*(419) -333 + j*(126) -125 + j*(-203) --144 + j*(-54) --21 + j*(157) -153 + j*(50) -77 + j*(-89) --10 + j*(-42) -33 + j*(-24) --8 + j*(-95) --121 + j*(-30) --54 + j*(96) -50 + j*(21) --81 + j*(-54) --167 + j*(165) -110 + j*(319) -340 + j*(62) -156 + j*(-168) -14 + j*(-24) -199 + j*(27) -245 + j*(-236) --26 + j*(-341) --163 + j*(-165) --98 + j*(-92) --140 + j*(-118) --202 + j*(-4) --97 + j*(97) --11 + j*(29) --64 + j*(-8) --75 + j*(61) -6 + j*(84) -62 + j*(32) -72 + j*(-46) -13 + j*(-127) --112 + j*(-111) --132 + j*(13) --25 + j*(25) --56 + j*(-96) --250 + j*(-49) --264 + j*(226) -14 + j*(361) -247 + j*(173) -189 + j*(-72) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -0 + j*(0) -];