diff --git a/0mq/funcall2.py b/0mq/funcall2.py index b316ff1..f858cdc 100644 --- a/0mq/funcall2.py +++ b/0mq/funcall2.py @@ -24,6 +24,7 @@ # ym = concore2.read(concore.iport['Y1'],"ym",init_simtime_ym) paired_transmitter = PairedTransmitter( remote_host="localhost", exposed_commands=[], + #remote_host="193.136.132.10", exposed_commands=[], remote_port=2345, listen_port=2346,) paired_transmitter.start_background_sync() ym = paired_transmitter.request_with_immediate_reply( diff --git a/concore.py b/concore.py index e3ec817..1459c76 100644 --- a/concore.py +++ b/concore.py @@ -77,11 +77,14 @@ def read(port, name, initstr): try: infile = open(inpath+str(port)+"/"+name); ins = infile.read() + infile.close() except: ins = initstr while len(ins)==0: time.sleep(delay) + infile = open(inpath+str(port)+"/"+name); ins = infile.read() + infile.close() retrycount += 1 s += ins inval = literal_eval(ins) @@ -110,4 +113,3 @@ def initval(simtime_val): val = literal_eval(simtime_val) simtime = val[0] return val[1:] - diff --git a/fri/DOCKER-README.md b/fri/DOCKER-README.md index c5be403..459d362 100644 --- a/fri/DOCKER-README.md +++ b/fri/DOCKER-README.md @@ -1,3 +1,24 @@ +# Install Docker:- + +Open Terminal and run the following commands:- + +```` +$ sudo apt-get update +$ sudo apt-get install curl +$ curl -fsSL https://get.docker.com/ | sh +```` +Optional command:- To run docker commands without sudo +```` +$ sudo usermod -aG docker +```` +The above command add the system username in the docker group, Restart the system to complete the process. + +After restart run + +```` +$ sudo service docker start +```` + # Building FRI Container Now, we elaborate on building FRI as a container, together with the Kong API Gateway. @@ -15,7 +36,7 @@ First build the Docker Container of the FRI. ```` $ git pull -$ sudo docker build -t fri . +$ docker build -t fri . ```` # Running Control-Core FRI with Kong as containers @@ -67,7 +88,7 @@ $ docker run -d --name kong \ Start FRI container ```` -$ nohup sudo docker run --name fri -p 8090:8081 fri > controlcore.out & +$ nohup sudo docker run --name fri -p 8090:8080 fri > controlcore.out & ```` Delete if there is a previously configured Kong service. If not, skip this step. First you need to find the ID-VALUE for the route with a GET command before deleting the route and service. @@ -107,17 +128,17 @@ $ tail -f controlcore.out ```` or ```` -$ sudo docker logs fri -f +$ docker logs fri -f ```` Find the FRI docker container ```` -$ sudo docker ps +$ docker ps ```` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES dfdd3b3d3308 fri "python main.py" 38 minutes ago Up 38 minutes 0.0.0.0:80->80/tcp fri Access the container ```` -$ sudo docker exec -it dfdd /bin/bash +$ docker exec -it dfdd /bin/bash ```` diff --git a/fri/README.md b/fri/README.md index ae129fd..b146465 100644 --- a/fri/README.md +++ b/fri/README.md @@ -4,9 +4,10 @@ The Control-Core File Receiving Interface (FRI) is built with is Python-3.10. It # Install Dependencies -Install Jupyter lab ```` -$ pip install jupyterlab +$ cd conore/fri + +$ pip3 install -r requirements.txt ```` # Running the FRI and a quick test. @@ -15,8 +16,6 @@ To run the FRI as a server: ```` $ cd conore/fri -$ git checkout dev - $ cd server $ python3 main.py diff --git a/fri/docker-compose.yml b/fri/docker-compose.yml new file mode 100644 index 0000000..542536f --- /dev/null +++ b/fri/docker-compose.yml @@ -0,0 +1,37 @@ +version: '3' + +services: + fri: + build: + context: . + image: fri + ports: + - 8090:8080 + command: tail -f /dev/null + + kong-database: + image: cassandra:3 + ports: + - 9042:9042 + + kong: + image: kong + depends_on: + - kong-database + environment: + KONG_DATABASE: cassandra + KONG_PG_HOST: kong-database + KONG_PG_PASSWORD: kong + KONG_CASSANDRA_CONTACT_POINTS: kong-database + KONG_PROXY_ACCESS_LOG: /dev/stdout + KONG_ADMIN_ACCESS_LOG: /dev/stdout + KONG_PROXY_ERROR_LOG: /dev/stderr + KONG_ADMIN_ERROR_LOG: /dev/stderr + KONG_ADMIN_LISTEN: 0.0.0.0:8001, 0.0.0.0:8444 ssl + ports: + - 80:8000 + - 8443:8443 + - 8001:8001 + - 8444:8444 + + \ No newline at end of file diff --git a/fri/requirements.txt b/fri/requirements.txt index 4ef52a1..8268e17 100644 --- a/fri/requirements.txt +++ b/fri/requirements.txt @@ -1,3 +1,4 @@ Flask gunicorn==20.1.0 FLASK_CORS +jupyterlab diff --git a/fri/server/main.py b/fri/server/main.py index 51f8f97..b2b790e 100644 --- a/fri/server/main.py +++ b/fri/server/main.py @@ -1,10 +1,11 @@ from flask import Flask, request, jsonify, send_file, send_from_directory from werkzeug.utils import secure_filename import os +import subprocess from subprocess import call from pathlib import Path import json -import subprocess +import platform from flask_cors import CORS, cross_origin cur_path = os.path.dirname(os.path.abspath(__file__)) @@ -21,8 +22,10 @@ @app.route('/upload/', methods=['POST']) def upload(dir): apikey = request.args.get('apikey') - dirname = secure_filename(dir) + "_" + apikey - + if(apikey == None): + dirname = secure_filename(dir) + else: + dirname = secure_filename(dir) + "_" + apikey if 'files[]' not in request.files: resp = jsonify({'message': 'No file in the request'}) resp.status_code = 400 @@ -38,7 +41,6 @@ def upload(dir): if not os.path.isdir(directory_name): os.mkdir(directory_name) - for file in files: if file: filename = secure_filename(file.filename) @@ -60,32 +62,52 @@ def upload(dir): return resp - # to download /build/?fetch=. For example, /build/test?fetch=sample1&apikey=xyz @app.route('/build/', methods=['POST']) def build(dir): graphml_file = request.args.get('fetch') apikey = request.args.get('apikey') - dirname = secure_filename(dir) + "_" + apikey + out_dir = request.args.get('outdir') + if(apikey == None): + dirname = secure_filename(dir) + else: + dirname = secure_filename(dir) + "_" + apikey makestudy_dir = dirname + "/" + graphml_file #for makestudy - dir_path = os.path.abspath(os.path.join(concore_path, graphml_file)) #path for ./build + if(out_dir == None or out_dir == ""): + dir_path = os.path.abspath(os.path.join(concore_path, graphml_file)) #path for ./build + else: + dir_path = os.path.abspath(os.path.join(concore_path, out_dir)) #path for ./build if not os.path.exists(dir_path): - proc = call(["./makestudy", makestudy_dir], cwd=concore_path) + if(platform.uname()[0]=='Windows'): + if(out_dir == None or out_dir == ""): + proc= call(["makestudy", makestudy_dir], shell=True, cwd=concore_path) + else: + proc= call(["makestudy", makestudy_dir, out_dir], shell=True, cwd=concore_path) + else: + if(out_dir == None or out_dir == ""): + proc= call(["./makestudy", makestudy_dir], cwd=concore_path) + else: + proc= call(["./makestudy", makestudy_dir, out_dir], cwd=concore_path) if(proc == 0): resp = jsonify({'message': 'Directory successfully created'}) resp.status_code = 201 else: resp = jsonify({'message': 'There is an Error'}) - resp.status_code = 500 - call(["./build"], cwd=dir_path) + resp.status_code = 500 + if(platform.uname()[0]=='Windows'): + call(["build"], cwd=dir_path, shell=True) + else: + call(["./build"], cwd=dir_path) return resp - @app.route('/debug/', methods=['POST']) def debug(dir): - dir = secure_filename(dir) - dir_path = os.path.abspath(os.path.join(concore_path, dir)) - proc = call(["./debug"], cwd=dir_path) + dir_name = secure_filename(dir) + dir_path = os.path.abspath(os.path.join(concore_path, dir_name)) + if(platform.uname()[0]=='Windows'): + proc=call(["debug"],shell=True, cwd=dir_path) + else: + proc = call(["./debug"], cwd=dir_path) if(proc == 0): resp = jsonify({'message': 'Close the pop window after obtaining result'}) resp.status_code = 201 @@ -95,12 +117,14 @@ def debug(dir): resp.status_code = 500 return resp - @app.route('/run/', methods=['POST']) def run(dir): - dir = secure_filename(dir) - dir_path = os.path.abspath(os.path.join(concore_path, dir)) - proc = call(["./run"], cwd=dir_path) + dir_name = secure_filename(dir) + dir_path = os.path.abspath(os.path.join(concore_path, dir_name)) + if(platform.uname()[0]=='Windows'): + proc=call(["run"],shell=True, cwd=dir_path) + else: + proc = call(["./run"], cwd=dir_path) if(proc == 0): resp = jsonify({'message': 'result prepared'}) resp.status_code = 201 @@ -112,9 +136,12 @@ def run(dir): @app.route('/stop/', methods=['POST']) def stop(dir): - dir = secure_filename(dir) - dir_path = os.path.abspath(os.path.join(concore_path, dir)) - proc = call(["./stop"], cwd=dir_path) + dir_name = secure_filename(dir) + dir_path = os.path.abspath(os.path.join(concore_path, dir_name)) + if(platform.uname()[0]=='Windows'): + proc=call(["stop"],shell=True, cwd=dir_path) + else: + proc = call(["./stop"], cwd=dir_path) if(proc == 0): resp = jsonify({'message': 'resources cleaned'}) resp.status_code = 201 @@ -127,9 +154,12 @@ def stop(dir): @app.route('/clear/', methods=['POST']) def clear(dir): - dir = secure_filename(dir) - dir_path = os.path.abspath(os.path.join(concore_path, dir)) - proc = call(["./clear"], cwd=dir_path) + dir_name = secure_filename(dir) + dir_path = os.path.abspath(os.path.join(concore_path, dir_name)) + if(platform.uname()[0]=='Windows'): + proc=call(["clear"],shell=True, cwd=dir_path) + else: + proc = call(["./clear"], cwd=dir_path) if(proc == 0): resp = jsonify({'message': 'result deleted'}) resp.status_code = 201 @@ -157,11 +187,13 @@ def download(dir): resp.status_code = 400 return resp - @app.route('/destroy/', methods=['DELETE']) def destroy(dir): dir = secure_filename(dir) - proc = call(["./destroy", dir], cwd=concore_path) + if(platform.uname()[0]=='Windows'): + proc=call(["destroy", dir],shell=True, cwd=concore_path) + else: + proc = call(["./destroy", dir], cwd=concore_path) if(proc == 0): resp = jsonify({'message': 'Successfuly deleted Dirctory'}) resp.status_code = 201 @@ -181,7 +213,6 @@ def getFilesList(dir): res = json.dumps(res) return res - @app.route('/openJupyter/', methods=['POST']) def openJupyter(): proc = subprocess.Popen(['jupyter', 'lab'], shell=False, stdout=subprocess.PIPE, cwd=concore_path) @@ -195,6 +226,5 @@ def openJupyter(): return resp - if __name__ == "__main__": app.run(host="0.0.0.0", port=5000) diff --git a/fri/test.py b/fri/test.py index 684c6ef..fe7e396 100644 --- a/fri/test.py +++ b/fri/test.py @@ -13,47 +13,45 @@ def upload(files): response = requests.request("POST", url, headers=headers, data=payload, files=files) print(response.text) - # # ******* # function to check build -def build(dir, graphml, apikey): - url = "http://127.0.0.1:5000/build/"+dir+"?"+"fetch="+graphml+"&"+"apikey="+apikey +def build(dir, graphml, outdir, apikey): + url = "http://127.0.0.1:5000/build/"+dir+"?"+"fetch="+graphml+"&"+"outdir="+outdir+"&"+"apikey="+apikey response = requests.request("POST", url) print(response.text) # function to debug -def debug(graphml): - url = "http://127.0.0.1:5000/debug/"+graphml +def debug(graphml, apikey): + url = "http://127.0.0.1:5000/debug/"+graphml+"?"+"apikey="+apikey response = requests.request("POST", url) print(response.text) # function to test run() method. -def run(graphml): - url = "http://127.0.0.1:5000/run/"+graphml +def run(graphml, apikey): + url = "http://127.0.0.1:5000/run/"+graphml+"?"+"apikey="+apikey response = requests.request("POST", url) print(response.text) -def clear(graphml): - url = "http://127.0.0.1:5000/clear/"+graphml +def clear(graphml, apikey): + url = "http://127.0.0.1:5000/clear/"+graphml+"?"+"apikey="+apikey response = requests.request("POST", url) print(response.text) -def stop(graphml): - url = "http://127.0.0.1:5000/stop/"+graphml +def stop(graphml, apikey): + url = "http://127.0.0.1:5000/stop/"+graphml+"?"+"apikey="+apikey response = requests.request("POST", url) print(response.text) - #function to destroy dir. -def destroy(dir): - url = "http://127.0.0.1:5000/destroy/" + dir +def destroy(dir, apikey): + url = "http://127.0.0.1:5000/destroy/" + dir+"?"+"apikey="+apikey response = requests.request("DELETE", url) print(response.text) -def getFilesList(dir, sub_dir = ""): - url = "http://127.0.0.1:5000/getFilesList/" + dir + "?"+"fetch="+sub_dir +def getFilesList(apikey, dir, sub_dir = ""): + url = "http://127.0.0.1:5000/getFilesList/" + dir + "?"+"fetch="+sub_dir+"&"+"apikey="+apikey response = requests.request("POST", url) print(response.text) @@ -63,8 +61,8 @@ def openJupyter(): print(response.text) # function to test download() method. -def download(dir, subDir, fileName ): - url = "http://127.0.0.1:5000/download/"+dir+"?"+"fetchDir="+subDir+"&"+"fetch="+ fileName +def download(dir, subDir, fileName , apikey ): + url = "http://127.0.0.1:5000/download/"+dir+"?"+"fetchDir="+subDir+"&"+"fetch="+ fileName+"&"+"apikey="+apikey urllib.request.urlretrieve(url, fileName) # file list to be uploaded @@ -83,25 +81,22 @@ def download(dir, subDir, fileName ): ('files[]',(file_name3,open(path_file3,'rb'),'application/octet-stream')), ] - upload(files) time.sleep(2) -build("test", "sample", "xyz") +build("test", "sample", "sample-anyname", "xyz") time.sleep(6) -method = input("methods - 1 for debug, 0 for run :") -if method == "1": - debug("sample") +method = int(input("methods - 1 for debug, 0 for run :")) +if method == 1: + debug("sample-anyname", "xyz") else: - run("sample") + run("sample-anyname", "xyz") time.sleep(2) -stop("sample") +stop("sample-anyname", "xyz") time.sleep(2) -getFilesList("sample", "cu") -getFilesList("sample", "pym") +getFilesList("xyz", "sample-anyname", "CU") +getFilesList("xyz","sample-anyname", "PYM") time.sleep(5) -download("sample", "cu", "u") -clear("sample") -destroy("sample") +download("sample-anyname", "CU", "u", "xyz") +clear("sample-anyname", "xyz") +destroy("sample-anyname", "xyz") openJupyter() - - diff --git a/nintan/README.md b/nintan/README.md new file mode 100644 index 0000000..0a6581b --- /dev/null +++ b/nintan/README.md @@ -0,0 +1,21 @@ +# Start IntanRHX in one window + +```` +$ Downloads/IntanRHX/IntanRHX +```` + +In order to run this example script successfully, the Intan RHX software should first be started, and through Network -> Remote TCP Control: + +Command Output should open a connection at 127.0.0.1, Port 5000. Status should read "Pending" + +Waveform Output (in the Data Output tab) should open a connection at 127.0.0.1, Port 5001. +Status should read "Pending" for the Waveform Port (Spike Port is unused for this example, and can be left disconnected) + +# Run RHXReadWaveformData.py in another window + +This will eventually be replaced by the step to start _concore._ + +```` +$ cd ~/concore/ +$ python3 RHXReadWaveformData.py +```` diff --git a/nintan/RHXReadWaveformData.py b/nintan/RHXReadWaveformData.py new file mode 100644 index 0000000..ab56fb6 --- /dev/null +++ b/nintan/RHXReadWaveformData.py @@ -0,0 +1,153 @@ +# In order to run this example script successfully, the Intan RHX software +# should first be started, and through Network -> Remote TCP Control: + +# Command Output should open a connection at 127.0.0.1, Port 5000. +# Status should read "Pending" + +# Waveform Output (in the Data Output tab) should open a connection at 127.0.0.1, Port 5001. +# Status should read "Pending" for the Waveform Port (Spike Port is unused for this example, +# and can be left disconnected) + +# Once these ports are opened, this script can be run to acquire ~1 second of wideband data from channel A-010, +# which can then be plotted assuming "matplotlib" is installed + +import time, socket + +# In order to plot the data, 'matplotlib' is required. +# If plotting is not needed, calls to plt can be removed and the data +# will still be present within the ReadWaveformDataDemo() function. +# 'matplotlib' can be installed with the command 'pip install matplotlib' +import matplotlib.pyplot as plt + +def readUint32(array, arrayIndex): + variableBytes = array[arrayIndex : arrayIndex + 4] + variable = int.from_bytes(variableBytes, byteorder='little', signed=False) + arrayIndex = arrayIndex + 4 + return variable, arrayIndex + +def readInt32(array, arrayIndex): + variableBytes = array[arrayIndex : arrayIndex + 4] + variable = int.from_bytes(variableBytes, byteorder='little', signed=True) + arrayIndex = arrayIndex + 4 + return variable, arrayIndex + +def readUint16(array, arrayIndex): + variableBytes = array[arrayIndex : arrayIndex + 2] + variable = int.from_bytes(variableBytes, byteorder='little', signed=False) + arrayIndex = arrayIndex + 2 + return variable, arrayIndex + +def ReadWaveformDataDemo(): + + # Declare buffer size for reading from TCP command socket + # This is the maximum number of bytes expected for 1 read. 1024 is plenty for a single text command + COMMAND_BUFFER_SIZE = 1024 # Increase if many return commands are expected + + # Declare buffer size for reading from TCP waveform socket. + # This is the maximum number of bytes expected for 1 read + + # There will be some TCP lag in both starting and stopping acquisition, so the exact number of data blocks may vary slightly. + # At 30 kHz with 1 channel, 1 second of wideband waveform data is 181,420 byte. See 'Calculations for accurate parsing' for more details + # To allow for some TCP lag in stopping acquisition resulting in slightly more than 1 second of data, 200000 should be a safe buffer size + WAVEFORM_BUFFER_SIZE = 200000 # Increase if channels, filter bands, or acquisition time increase + + # Connect to TCP command server - default home IP address at port 5000 + print('Connecting to TCP command server...') + scommand = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + scommand.connect(('127.0.0.1', 5000)) + + # Connect to TCP waveform server - default home IP address at port 5001 + print('Connecting to TCP waveform server...') + swaveform = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + swaveform.connect(('127.0.0.1', 5001)) + + # Query runmode from RHX software + scommand.sendall(b'get runmode') + commandReturn = str(scommand.recv(COMMAND_BUFFER_SIZE), "utf-8") + isStopped = commandReturn == "Return: RunMode Stop" + + # If controller is running, stop it + if not isStopped: + scommand.sendall(b'set runmode stop') + time.sleep(0.1) # Allow time for RHX software to accept this command before the next one comes + + # Query sample rate from RHX software + scommand.sendall(b'get sampleratehertz') + commandReturn = str(scommand.recv(COMMAND_BUFFER_SIZE), "utf-8") + expectedReturnString = "Return: SampleRateHertz " + if commandReturn.find(expectedReturnString) == -1: # Look for "Return: SampleRateHertz N" where N is the sample rate + raise Exception('Unable to get sample rate from server') + else: + sampleRate = float(commandReturn[len(expectedReturnString):]) + + # Calculate timestep from sample rate + timestep = 1 / sampleRate + + # Clear TCP data output to ensure no TCP channels are enabled + scommand.sendall(b'execute clearalldataoutputs') + time.sleep(0.1) + + # Send TCP commands to set up TCP Data Output Enabled for wide + # band of channel A-010 + scommand.sendall(b'set a-010.tcpdataoutputenabled true') + time.sleep(0.1) + + # Calculations for accurate parsing + # At 30 kHz with 1 channel, 1 second of wideband waveform data (including magic number, timestamps, and amplifier data) is 181,420 bytes + # N = (framesPerBlock * waveformBytesPerFrame + SizeOfMagicNumber) * NumBlocks where: + # framesPerBlock = 128 ; standard data block size used by Intan + # waveformBytesPerFrame = SizeOfTimestamp + SizeOfSample ; timestamp is a 4-byte (32-bit) int, and amplifier sample is a 2-byte (16-bit) unsigned int + # SizeOfMagicNumber = 4; Magic number is a 4-byte (32-bit) unsigned int + # NumBlocks = NumFrames / framesPerBlock ; At 30 kHz, 1 second of data has 30000 frames. NumBlocks must be an integer value, so round up to 235 + + framesPerBlock = 128 + waveformBytesPerFrame = 4 + 2 + waveformBytesPerBlock = framesPerBlock * waveformBytesPerFrame + 4 + + # Run controller for 1 second + scommand.sendall(b'set runmode run') + time.sleep(1) + scommand.sendall(b'set runmode stop') + + # Read waveform data + rawData = swaveform.recv(WAVEFORM_BUFFER_SIZE) + if len(rawData) % waveformBytesPerBlock != 0: + raise Exception('An unexpected amount of data arrived that is not an integer multiple of the expected data size per block') + numBlocks = int(len(rawData) / waveformBytesPerBlock) + + rawIndex = 0 # Index used to read the raw data that came in through the TCP socket + amplifierTimestamps = [] # List used to contain scaled timestamp values in seconds + amplifierData = [] # List used to contain scaled amplifier data in microVolts + + for block in range(numBlocks): + # Expect 4 bytes to be TCP Magic Number as uint32. + # If not what's expected, raise an exception. + magicNumber, rawIndex = readUint32(rawData, rawIndex) + if magicNumber != 0x2ef07a08: + raise Exception('Error... magic number incorrect') + + # Each block should contain 128 frames of data - process each + # of these one-by-one + for frame in range(framesPerBlock): + # Expect 4 bytes to be timestamp as int32. + rawTimestamp, rawIndex = readInt32(rawData, rawIndex) + + # Multiply by 'timestep' to convert timestamp to seconds + amplifierTimestamps.append(rawTimestamp * timestep) + + # Expect 2 bytes of wideband data. + rawSample, rawIndex = readUint16(rawData, rawIndex) + + # Scale this sample to convert to microVolts + amplifierData.append(0.195 * (rawSample - 32768)) + + + # If using matplotlib to plot is not desired, the following plot lines can be removed. + # Data is still accessible at this point in the amplifierTimestamps and amplifierData + plt.plot(amplifierTimestamps, amplifierData) + plt.title('A-010 Amplifier Data') + plt.xlabel('Time (s)') + plt.ylabel('Voltage (uV)') + plt.show() + +ReadWaveformDataDemo() \ No newline at end of file diff --git a/nintan/cpymax.py b/nintan/cpymax.py new file mode 100644 index 0000000..5c767ea --- /dev/null +++ b/nintan/cpymax.py @@ -0,0 +1,29 @@ +import concore +import time +concore.delay = 0.01 +#Nsim = 100 +init_simtime_u = "[0.0, 0.0, 0.0]" +init_simtime_ym = "[0.0, 0.0, 0.0]" +minElasped = 10000000 +maxElasped = 0 +sumElasped = 0 +u = concore.initval(init_simtime_u) +wallclock1 = time.perf_counter() +while(concore.simtime 100: + u[0] = 1.0 + elif abs(ym[1]) < 1: + u[0] = 0.01 + + elif bangbang: + if ym[0] > 0: + u[0] = 0.9 + else: + u[0] = 0.1 + else: + try: + u[0] = float(literal_eval(input())) + except: + print("bad input, using .5 instead") + u[0] = 0.5 + print("ym="+str(ym[0])+" u="+str(u[0])); + print("min="+str(minElasped)) + print("avg="+str(sumElasped/max(1,concore.simtime))) + print("max="+str(maxElasped)) + concore.write(1,"u",u); + wallclock2 = time.perf_counter() + elasped = wallclock2-wallclock1 + sumElasped += elasped + wallclock1 = wallclock2 + minElasped = min(minElasped, elasped) + maxElasped = max(maxElasped, elasped) + +print("retry="+str(concore.retrycount)) +print("min="+str(minElasped)) +print("avg="+str(sumElasped/concore.maxtime)) +print("max="+str(maxElasped)) diff --git a/nintan/cstim0.py b/nintan/cstim0.py new file mode 100644 index 0000000..c0ec58b --- /dev/null +++ b/nintan/cstim0.py @@ -0,0 +1,32 @@ +import concore +from ast import literal_eval +import time +concore.delay = 0.001 +init_simtime_u = "[0.0, 0.0, 0.0]" +init_simtime_ym = "[0.0, 0.0, 0.0]" +minElasped = 10000000 +maxElasped = 0 +sumElasped = 0 +u = concore.initval(init_simtime_u) +wallclock1 = time.perf_counter() +while(concore.simtime Remote TCP Control: +# Command Output should open a connection at 127.0.0.1, Port 5000. +# Status should read "Pending" +# Waveform Output (in the Data Output tab) should open a connection at 127.0.0.1, Port 5001. +# Status should read "Pending" for the Waveform Port (Spike Port is unused for this example, +# and can be left disconnected) +# Once these ports are opened, this script can be run to acquire ~1 second of wideband data from channel A-010, + +import concore +import time +import threading +import socket +import matplotlib.pyplot as plt +import numpy as np + +try: + showPlot = concore.params['plot'] +except: + showPlot = 0 + +try: + tsamp = concore.params['tsamp'] + if tsamp > 1: + tsamp = 1 +except: + tsamp = 1 + +def validseq(t): + validindex = 0 + for i in range(0,len(t)-1): + if t[i] >= t[i+1]: + print('i='+str(i)+': '+str(t[i])+'>='+str(t[i+1])+' len='+str(len(t))) + validindex = i+1 + return validindex + +def extract(amplifierData): + s = 0.0 + for data in amplifierData: + s += data + #time.sleep(0.5/len(amplifierData)) #make extract really slow for testing + return s/len(amplifierData) + +def smooth_freq(y,bins): + f=np.fft.fft(y) + f0=np.abs(f[-(bins-1):-1]) + f1=np.abs(f[-bins:-2]) + f2=np.abs(f[-(bins+1):-3]) + fa=f2+2*f1+f2 + return bins-np.argmax((np.abs(fa))) + +def dom_freq(y,t): + ttot = (t[-1] - t[0]) * len(y)/(len(y)-1) + f = np.fft.fft(y) + fi = np.argmax((np.abs(f))) + return np.fft.fftfreq(len(y))[fi]*len(y)/ttot + +def readUint32(array, arrayIndex): + variableBytes = array[arrayIndex : arrayIndex + 4] + variable = int.from_bytes(variableBytes, byteorder='little', signed=False) + arrayIndex = arrayIndex + 4 + return variable, arrayIndex + +def readInt32(array, arrayIndex): + variableBytes = array[arrayIndex : arrayIndex + 4] + variable = int.from_bytes(variableBytes, byteorder='little', signed=True) + arrayIndex = arrayIndex + 4 + return variable, arrayIndex + +def readUint16(array, arrayIndex): + variableBytes = array[arrayIndex : arrayIndex + 2] + variable = int.from_bytes(variableBytes, byteorder='little', signed=False) + arrayIndex = arrayIndex + 2 + return variable, arrayIndex + +def clearall(): + # Clear TCP data output to ensure no TCP channels are enabled + scommand.sendall(b'execute clearalldataoutputs') + time.sleep(0.1) + # Send TCP commands to set up TCP Data Output Enabled for wide + # band of channel A-010 + scommand.sendall(b'set a-010.tcpdataoutputenabled true') + time.sleep(0.1) + +def acq(): + # Run controller for tsamp second + scommand.sendall(b'set runmode run') + time.sleep(tsamp) + scommand.sendall(b'set runmode stop') + + # Suggestion from Adrian at Intan 4/21/22 + t1 = time.perf_counter() + time.sleep(0.04) + scommand.sendall(b'get runmode') + commandReturn = str(scommand.recv(COMMAND_BUFFER_SIZE), "utf-8") + isStopped = commandReturn == "Return: RunMode Stop" + while not isStopped: + time.sleep(0.01) + print('Wait') + scommand.sendall(b'get runmode') + commandReturn = str(scommand.recv(COMMAND_BUFFER_SIZE), "utf-8") + isStopped = commandReturn == "Return: RunMode Stop" + t2 = time.perf_counter() + + # Read waveform data + rawData = swaveform.recv(WAVEFORM_BUFFER_SIZE) + if len(rawData) % waveformBytesPerBlock != 0: + raise Exception('unexpected amount of data') + numBlocks = int(len(rawData) / waveformBytesPerBlock) + + rawIndex = 0 # Index used to read the raw data + + for block in range(numBlocks): + # Expect 4 bytes to be TCP Magic Number as uint32. + # If not what's expected, raise an exception. + magicNumber, rawIndex = readUint32(rawData, rawIndex) + if magicNumber != 0x2ef07a08: + raise Exception('Error... magic number incorrect') + + # Each block should contain 128 frames of data - process each + # of these one-by-one + for frame in range(framesPerBlock): + # Expect 4 bytes to be timestamp as int32. + rawTimestamp, rawIndex = readInt32(rawData, rawIndex) + + # Multiply by 'timestep' to convert timestamp to seconds + amplifierTimestamps.append(rawTimestamp * timestep) + + # Expect 2 bytes of wideband data. + rawSample, rawIndex = readUint16(rawData, rawIndex) + + # Scale this sample to convert to microVolts + amplifierData.append(0.195 * (rawSample - 32768)) + t3 = time.perf_counter() + print(str(t2-t1)+' stop time '+str(t3-t2)+' parse time') + +#initialization +# Declare buffer size for reading from TCP command socket +# This is the maximum number of bytes expected for 1 read. 1024 is plenty for a single text command +COMMAND_BUFFER_SIZE = 1024 # Increase if many return commands are expected +# Declare buffer size for reading from TCP waveform socket. +# This is the maximum number of bytes expected for 1 read +# There will be some TCP lag in both starting and stopping acquisition, so the exact number of data blocks may vary slightly. +# At 30 kHz with 1 channel, 1 second of wideband waveform data is 181,420 byte. See 'Calculations for accurate parsing' for more details +# To allow for some TCP lag in stopping acquisition resulting in slightly more than 1 second of data, 200000 should be a safe buffer size +WAVEFORM_BUFFER_SIZE = 200000 # Increase if channels, filter bands, or acquisition time increase +# Connect to TCP command server - default home IP address at port 5000 +print('Connecting to TCP command server...') +scommand = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +scommand.connect(('127.0.0.1', 5000)) +# Connect to TCP waveform server - default home IP address at port 5001 +print('Connecting to TCP waveform server...') +swaveform = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +swaveform.connect(('127.0.0.1', 5001)) +# Query runmode from RHX software +scommand.sendall(b'get runmode') +commandReturn = str(scommand.recv(COMMAND_BUFFER_SIZE), "utf-8") +isStopped = commandReturn == "Return: RunMode Stop" +# If controller is running, stop it +if not isStopped: + scommand.sendall(b'set runmode stop') + time.sleep(0.1) # Allow time for RHX software to accept this command before the next one comes + +scommand.sendall(b'set TCPNumberDataBlocksPerWrite 20') +time.sleep(0.1) + +# Query sample rate from RHX software +scommand.sendall(b'get sampleratehertz') +commandReturn = str(scommand.recv(COMMAND_BUFFER_SIZE), "utf-8") +expectedReturnString = "Return: SampleRateHertz " +if commandReturn.find(expectedReturnString) == -1: # Look for "Return: SampleRateHertz N" where N is the sample rate + raise Exception('Unable to get sample rate from server') +else: + sampleRate = float(commandReturn[len(expectedReturnString):]) + +# Calculate timestep from sample rate +timestep = 1 / sampleRate + + +# Calculations for accurate parsing +# At 30 kHz with 1 channel, 1 second of wideband waveform data (including magic number, timestamps, and amplifier data) is 181,420 bytes +# N = (framesPerBlock * waveformBytesPerFrame + SizeOfMagicNumber) * NumBlocks where: +# framesPerBlock = 128 ; standard data block size used by Intan +# waveformBytesPerFrame = SizeOfTimestamp + SizeOfSample ; timestamp is a 4-byte (32-bit) int, and amplifier sample is a 2-byte (16-bit) unsigned int +# SizeOfMagicNumber = 4; Magic number is a 4-byte (32-bit) unsigned int +# NumBlocks = NumFrames / framesPerBlock ; At 30 kHz, 1 second of data has 30000 frames. NumBlocks must be an integer value, so round up to 235 + +framesPerBlock = 128 +waveformBytesPerFrame = 4 + 2 +waveformBytesPerBlock = framesPerBlock * waveformBytesPerFrame + 4 + +clearall() + +concore.delay = 0.01 +init_simtime_u = "[0.0, 0.0, 0.0]" +init_simtime_ym = "[0.0, 0.0, 0.0]" + +ym = concore.initval(init_simtime_ym) + +acq_thread = threading.Thread(target=acq, daemon=True) +nxtacq_thread = threading.Thread(target=acq, daemon=True) +amplifierTimestamps = [] +amplifierData = [] +acq_thread.start() +while(concore.simtime 1: + tsamp = 1 +except: + tsamp = 1 + +def validseq(t): + validindex = 0 + for i in range(0,len(t)-1): + if t[i] >= t[i+1]: + print('i='+str(i)+': '+str(t[i])+'>='+str(t[i+1])+' len='+str(len(t))) + validindex = i+1 + return validindex + +def extract(amplifierData): + s = 0.0 + for data in amplifierData: + s += data + #time.sleep(0.5/len(amplifierData)) #make extract really slow for testing + return s/len(amplifierData) + +def readUint32(array, arrayIndex): + variableBytes = array[arrayIndex : arrayIndex + 4] + variable = int.from_bytes(variableBytes, byteorder='little', signed=False) + arrayIndex = arrayIndex + 4 + return variable, arrayIndex + +def readInt32(array, arrayIndex): + variableBytes = array[arrayIndex : arrayIndex + 4] + variable = int.from_bytes(variableBytes, byteorder='little', signed=True) + arrayIndex = arrayIndex + 4 + return variable, arrayIndex + +def readUint16(array, arrayIndex): + variableBytes = array[arrayIndex : arrayIndex + 2] + variable = int.from_bytes(variableBytes, byteorder='little', signed=False) + arrayIndex = arrayIndex + 2 + return variable, arrayIndex + +def clearall(): + # Clear TCP data output to ensure no TCP channels are enabled + scommand.sendall(b'execute clearalldataoutputs') + time.sleep(0.1) + # Send TCP commands to set up TCP Data Output Enabled for wide + # band of channel A-010 + scommand.sendall(b'set a-010.tcpdataoutputenabled true') + time.sleep(0.1) + +def acq(): + # Run controller for tsamp second + scommand.sendall(b'set runmode run') + time.sleep(tsamp) + scommand.sendall(b'set runmode stop') + + # Read waveform data + rawData = swaveform.recv(WAVEFORM_BUFFER_SIZE) + if len(rawData) % waveformBytesPerBlock != 0: + raise Exception('unexpected amount of data') + numBlocks = int(len(rawData) / waveformBytesPerBlock) + + rawIndex = 0 # Index used to read the raw data + + for block in range(numBlocks): + # Expect 4 bytes to be TCP Magic Number as uint32. + # If not what's expected, raise an exception. + magicNumber, rawIndex = readUint32(rawData, rawIndex) + if magicNumber != 0x2ef07a08: + raise Exception('Error... magic number incorrect') + + # Each block should contain 128 frames of data - process each + # of these one-by-one + for frame in range(framesPerBlock): + # Expect 4 bytes to be timestamp as int32. + rawTimestamp, rawIndex = readInt32(rawData, rawIndex) + + # Multiply by 'timestep' to convert timestamp to seconds + amplifierTimestamps.append(rawTimestamp * timestep) + + # Expect 2 bytes of wideband data. + rawSample, rawIndex = readUint16(rawData, rawIndex) + + # Scale this sample to convert to microVolts + amplifierData.append(0.195 * (rawSample - 32768)) + + +#initialization +# Declare buffer size for reading from TCP command socket +# This is the maximum number of bytes expected for 1 read. 1024 is plenty for a single text command +COMMAND_BUFFER_SIZE = 1024 # Increase if many return commands are expected +# Declare buffer size for reading from TCP waveform socket. +# This is the maximum number of bytes expected for 1 read +# There will be some TCP lag in both starting and stopping acquisition, so the exact number of data blocks may vary slightly. +# At 30 kHz with 1 channel, 1 second of wideband waveform data is 181,420 byte. See 'Calculations for accurate parsing' for more details +# To allow for some TCP lag in stopping acquisition resulting in slightly more than 1 second of data, 200000 should be a safe buffer size +WAVEFORM_BUFFER_SIZE = 200000 # Increase if channels, filter bands, or acquisition time increase +# Connect to TCP command server - default home IP address at port 5000 +print('Connecting to TCP command server...') +scommand = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +scommand.connect(('127.0.0.1', 5000)) +# Connect to TCP waveform server - default home IP address at port 5001 +print('Connecting to TCP waveform server...') +swaveform = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +swaveform.connect(('127.0.0.1', 5001)) +# Query runmode from RHX software +scommand.sendall(b'get runmode') +commandReturn = str(scommand.recv(COMMAND_BUFFER_SIZE), "utf-8") +isStopped = commandReturn == "Return: RunMode Stop" +# If controller is running, stop it +if not isStopped: + scommand.sendall(b'set runmode stop') + time.sleep(0.1) # Allow time for RHX software to accept this command before the next one comes + +scommand.sendall(b'set TCPNumberDataBlocksPerWrite 20') +time.sleep(0.1) + +# Query sample rate from RHX software +scommand.sendall(b'get sampleratehertz') +commandReturn = str(scommand.recv(COMMAND_BUFFER_SIZE), "utf-8") +expectedReturnString = "Return: SampleRateHertz " +if commandReturn.find(expectedReturnString) == -1: # Look for "Return: SampleRateHertz N" where N is the sample rate + raise Exception('Unable to get sample rate from server') +else: + sampleRate = float(commandReturn[len(expectedReturnString):]) + +# Calculate timestep from sample rate +timestep = 1 / sampleRate + + +# Calculations for accurate parsing +# At 30 kHz with 1 channel, 1 second of wideband waveform data (including magic number, timestamps, and amplifier data) is 181,420 bytes +# N = (framesPerBlock * waveformBytesPerFrame + SizeOfMagicNumber) * NumBlocks where: +# framesPerBlock = 128 ; standard data block size used by Intan +# waveformBytesPerFrame = SizeOfTimestamp + SizeOfSample ; timestamp is a 4-byte (32-bit) int, and amplifier sample is a 2-byte (16-bit) unsigned int +# SizeOfMagicNumber = 4; Magic number is a 4-byte (32-bit) unsigned int +# NumBlocks = NumFrames / framesPerBlock ; At 30 kHz, 1 second of data has 30000 frames. NumBlocks must be an integer value, so round up to 235 + +framesPerBlock = 128 +waveformBytesPerFrame = 4 + 2 +waveformBytesPerBlock = framesPerBlock * waveformBytesPerFrame + 4 + +clearall() + +concore.delay = 0.01 +init_simtime_u = "[0.0, 0.0, 0.0]" +init_simtime_ym = "[0.0, 0.0, 0.0]" + +ym = concore.initval(init_simtime_ym) + +acq_thread = threading.Thread(target=acq, daemon=True) +nxtacq_thread = threading.Thread(target=acq, daemon=True) +amplifierTimestamps = [] +amplifierData = [] +acq_thread.start() +while(concore.simtime= 2: + print("-") + writer.write_one_sample_one_line(data=0,timeout=10) + time.sleep(PULSE_WIDTH*(1.0-ulocal)) + +pwm_thread = threading.Thread(target=pwm, daemon=True) + +def cnt(): + count = 0 + while(True): + print(count) + count = (count + 1)%10 + time.sleep(1) + +cnt_thread = threading.Thread(target=cnt, daemon=True) + +task = nidaqmx.Task() +task.do_channels.add_do_chan("Dev1/port0/line0") +writer = DigitalSingleChannelWriter(task.out_stream) + +concore.delay = 0.01 +init_simtime_u = "[0.0, 0.0, 0.0]" +init_simtime_ym = "[0.0, 0.0, 0.0]" + +ym = concore.initval(init_simtime_ym) + +cnt_thread.start() +pwm_thread.start() +while(concore.simtime + + + + + + + + + + + + + + + + + + + + + + XZ:powermetermax.py + + + + + + + + + + + PZ:pmpymax.py + + + + + + + + + + + CZ:cpymax.py + + + + + + + + + + + + + VXP + + + + + + + + + + + + + VP + + + + + + + + + + + + VC + + + + + + + + + + + + + VXC + + + + + + + + diff --git a/nintan/testZmax.graphml b/nintan/testZmax.graphml new file mode 100644 index 0000000..bfc4a53 --- /dev/null +++ b/nintan/testZmax.graphml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + CZ:cpymax.py + + + + + + + + + + + PZ:pmpymax.py + + + + + + + + + + + + + VCZ + + + + + + + + + + + + + VPZ + + + + + + + + diff --git a/nintan/testplot.graphml b/nintan/testplot.graphml new file mode 100644 index 0000000..858fe78 --- /dev/null +++ b/nintan/testplot.graphml @@ -0,0 +1,304 @@ + + + + + + + + + + + + CZ:cstim.py + + + + + + + + + + + PZ:pstim0.py + + + + + + + + + + + AZ:plotym.py + + + + + + + + + + CU + + + + + + + + + + + + PYM + + + + + + + + + + + + AYM + + + + + + + + 1679679128844 + + DEL_NODE + WyJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiXQ== + + + ADD_NODE + WyJDWjpjc3RpbS5weSIseyJ3aWR0aCI6MTA0LCJoZWlnaHQiOjUwLCJzaGFwZSI6InJlY3RhbmdsZSIsIm9wYWNpdHkiOjEsImJhY2tncm91bmRDb2xvciI6IiNmZmNjMDAiLCJib3JkZXJDb2xvciI6IiMwMDAiLCJib3JkZXJXaWR0aCI6MX0sIm9yZGluIix7IngiOjEwMCwieSI6MTAwfSx7fSwiYjExOTNjM2YtZWRjMi00MWZmLWEzMWQtMTM2MDZmNDRhZTVlIl0= + + 2e86d4fed8aafe8ef09f1cf40708efba + + + 1679679163391 + + DEL_NODE + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiXQ== + + + ADD_NODE + WyJQWjpwc3RpbS5weSIseyJ3aWR0aCI6MTA0LCJoZWlnaHQiOjUwLCJzaGFwZSI6InJlY3RhbmdsZSIsIm9wYWNpdHkiOjEsImJhY2tncm91bmRDb2xvciI6IiNmZmNjMDAiLCJib3JkZXJDb2xvciI6IiMwMDAiLCJib3JkZXJXaWR0aCI6MX0sIm9yZGluIix7IngiOjEwMy43MzI0NDY2NDExNTI4NSwieSI6MjQxLjYxODYyMDUzNTc5MDN9LHt9LCJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiXQ== + + 80c0f78366d87d0e9cb4a9f779ef910d + + + 1679679171029 + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTEwLCJ5IjoxMTB9LHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9XQ== + + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9LHsieCI6MTEwLCJ5IjoxMTB9XQ== + + c57e6b6829d726b5f03a833b44307338 + + + 1679679176150 + + DEL_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLCJ0YXJnZXRJRCI6ImEyNDU1ZTBjLWRiMDMtNGFiNy04M2M2LTZlYmUwNjI3YzhkOCIsImxhYmVsIjoiQ1AiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsImJhY2tncm91bmRDb2xvciI6bnVsbCwic2hhcGUiOiJzb2xpZCJ9LCJpZCI6IjA5OWM4MTUyLWZiY2MtNDAwMC05NjZkLWFmNWRiNWRiMDdmNyJ9XQ== + + 2b810795ac0dbd48c4b6260f5104c3b1 + + + 1679679205932 + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9LHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyNDEuNjE4NjIwNTM1NzkwM31d + + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyNDEuNjE4NjIwNTM1NzkwM30seyJ4IjoxMDMuNzMyNDQ2NjQxMTUyODUsInkiOjIwNS44MDQwMjk5MTM4MDY1N31d + + 18d729b7e03e83e84b6fbd286d788f71 + + + 1679679211535 + + DEL_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLCJ0YXJnZXRJRCI6ImIxMTkzYzNmLWVkYzItNDFmZi1hMzFkLTEzNjA2ZjQ0YWU1ZSIsImxhYmVsIjoiUEMiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsImJhY2tncm91bmRDb2xvciI6bnVsbCwic2hhcGUiOiJzb2xpZCJ9LCJpZCI6ImNkNjdjNzg0LTI0OWQtNDk4My1hMzdjLWM0NmMyZWI4OGRkMiJ9XQ== + + e08334b92279b7c8a1863601555d0c32 + + + 1679679230448 + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiQ1AiLHRydWVd + + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiVSIsdHJ1ZV0= + + d9ee24f85d386f27731edf62627e54a7 + + + 1679679244531 + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiVSIsdHJ1ZV0= + + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiQ1UiLHRydWVd + + 5dc0d5c06a55c52b36813323f7847b41 + + + 1679679254340 + + UPDATE_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiUEMiLHRydWVd + + + UPDATE_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiUFlNIix0cnVlXQ== + + 6741405b1346bb7d4696e6f43d8dd767 + + + 1680063133865 + + DEL_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiXQ== + + + ADD_NODE + WyJBUTpwYWNxLnB5Iix7IndpZHRoIjoxMDQsImhlaWdodCI6NTAsInNoYXBlIjoicmVjdGFuZ2xlIiwib3BhY2l0eSI6MSwiYmFja2dyb3VuZENvbG9yIjoiI2ZmY2MwMCIsImJvcmRlckNvbG9yIjoiIzAwMCIsImJvcmRlcldpZHRoIjoxfSwib3JkaW4iLHsieCI6MzM5LCJ5IjoxNTZ9LHt9LCJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiXQ== + + 3287a038f8fe444dee54a3810ee43e4d + + + 1680063141667 + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6MTEwLCJ5IjoxMTB9LHsieCI6Mjc2LCJ5IjoxNTR9XQ== + + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6Mjc2LCJ5IjoxNTR9LHsieCI6MTEwLCJ5IjoxMTB9XQ== + + f7d58daaa5012b5681a7083b83a4631b + + + 1680063155805 + + DEL_EDGE + WyIxM2I4NWVmMS01YjM2LTQ0MmEtYmYxZC1lMGY1YTE5Y2IwNWUiXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLCJ0YXJnZXRJRCI6ImUwYzM1ZmE2LTQ4NWMtNGIyOS1hNTM5LTBiZmFjMDBlZDMyMCIsImlkIjoiMTNiODVlZjEtNWIzNi00NDJhLWJmMWQtZTBmNWExOWNiMDVlIn1d + + cc6959d442babdc676db4b9c10832c42 + + + 1680063168225 + + ADD_EDGE + W3sibGFiZWwiOiJQWU0iLCJzb3VyY2UiOiJlZTUxZWM5NC1hZTZkLTQ3NmEtYjlhOC1kNmFmNjg5ZmIxMjUiLCJ0YXJnZXQiOiJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsInNoYXBlIjoic29saWQifSwiYmVuZERhdGEiOnsiYmVuZERpc3RhbmNlIjoyMi45NTU5ODkxMTI2NTAxNjIsImJlbmRXZWlnaHQiOjAuNTA4MDY3NzAxOTg3NDI4NSwiYmVuZFBvaW50Ijp7IngiOjEzNC4xMDQxNTA3MzU2NTM3MiwieSI6MTUyLjgxNzM2MzIzMzU5ODM3fX0sInNvdXJjZUlEIjoiYTI0NTVlMGMtZGIwMy00YWI3LTgzYzYtNmViZTA2MjdjOGQ4IiwidGFyZ2V0SUQiOiJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLCJ0eXBlIjoib3JkaW4iLCJpZCI6IjZjNDU5ZThkLTFkZWQtNDhkNy05ZTIyLWNiMGE2ZTc5MjkxYiJ9XQ== + + + DEL_EDGE + WyI2YzQ1OWU4ZC0xZGVkLTQ4ZDctOWUyMi1jYjBhNmU3OTI5MWIiXQ== + + 686c147a5abc46f1df084baa5e2cf814 + + + 1680063177212 + + DEL_EDGE + WyIzNmUyMTE3Ny04YzdhLTQ4YjQtYTE2ZS1mYTJhOWUxZjk4ZjciXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLCJ0YXJnZXRJRCI6ImIxMTkzYzNmLWVkYzItNDFmZi1hMzFkLTEzNjA2ZjQ0YWU1ZSIsImxhYmVsIjoiQVlNIiwic3R5bGUiOnsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiaWQiOiIzNmUyMTE3Ny04YzdhLTQ4YjQtYTE2ZS1mYTJhOWUxZjk4ZjcifV0= + + edb67f19b4a7824d05206aa4e881a1a6 + + + 1680063187427 + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6Mjc2LCJ5IjoxNTR9LHsieCI6MzM5LCJ5IjoxNTZ9XQ== + + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6MzM5LCJ5IjoxNTZ9LHsieCI6Mjc2LCJ5IjoxNTR9XQ== + + 66858450ca671faf70f4c4405304cabc + + + 1680063190935 + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBUTpwYWNxLnB5Iix0cnVlXQ== + + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjoiLHRydWVd + + 3f0ebff9c7be28e0d2f31fd458269284 + + + 1680063200154 + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjoiLHRydWVd + + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjpwYWNxLnB5Iix0cnVlXQ== + + 06c7aa1eb3de8407b009e0837f191c3f + + + 1680112486999 + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjpwYWNxLnB5Iix0cnVlXQ== + + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjExMywiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjpwbG90eW0ucHkiLHRydWVd + + 1e1c7a613c4ff82dadf9f654081eacc7 + + + 1680112660989 + + UPDATE_NODE + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJQWjpwc3RpbS5weSIsdHJ1ZV0= + + + UPDATE_NODE + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsid2lkdGgiOjExMywiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJQWjpwc3RpbTAucHkiLHRydWVd + + da27b84084e25fd34107340e91be8c25 + + + \ No newline at end of file diff --git a/nintan/teststim.graphml b/nintan/teststim.graphml new file mode 100644 index 0000000..7a78249 --- /dev/null +++ b/nintan/teststim.graphml @@ -0,0 +1,161 @@ + + + + + + + + + + + + CZ:cstim.py + + + + + + + + + + + PZ:pstim.py + + + + + + + + + + CU + + + + + + + + + + + + PYM + + + + + + + + 1679679128844 + + DEL_NODE + WyJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiXQ== + + + ADD_NODE + WyJDWjpjc3RpbS5weSIseyJ3aWR0aCI6MTA0LCJoZWlnaHQiOjUwLCJzaGFwZSI6InJlY3RhbmdsZSIsIm9wYWNpdHkiOjEsImJhY2tncm91bmRDb2xvciI6IiNmZmNjMDAiLCJib3JkZXJDb2xvciI6IiMwMDAiLCJib3JkZXJXaWR0aCI6MX0sIm9yZGluIix7IngiOjEwMCwieSI6MTAwfSx7fSwiYjExOTNjM2YtZWRjMi00MWZmLWEzMWQtMTM2MDZmNDRhZTVlIl0= + + 2e86d4fed8aafe8ef09f1cf40708efba + + + 1679679163391 + + DEL_NODE + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiXQ== + + + ADD_NODE + WyJQWjpwc3RpbS5weSIseyJ3aWR0aCI6MTA0LCJoZWlnaHQiOjUwLCJzaGFwZSI6InJlY3RhbmdsZSIsIm9wYWNpdHkiOjEsImJhY2tncm91bmRDb2xvciI6IiNmZmNjMDAiLCJib3JkZXJDb2xvciI6IiMwMDAiLCJib3JkZXJXaWR0aCI6MX0sIm9yZGluIix7IngiOjEwMy43MzI0NDY2NDExNTI4NSwieSI6MjQxLjYxODYyMDUzNTc5MDN9LHt9LCJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiXQ== + + 2feb956b0a2b0ced965fd91f629e0b76 + + + 1679679171029 + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTEwLCJ5IjoxMTB9LHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9XQ== + + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9LHsieCI6MTEwLCJ5IjoxMTB9XQ== + + 0f3b77449604c51ef9be645ae0d7d757 + + + 1679679176150 + + DEL_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLCJ0YXJnZXRJRCI6ImEyNDU1ZTBjLWRiMDMtNGFiNy04M2M2LTZlYmUwNjI3YzhkOCIsImxhYmVsIjoiQ1AiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsImJhY2tncm91bmRDb2xvciI6bnVsbCwic2hhcGUiOiJzb2xpZCJ9LCJpZCI6IjA5OWM4MTUyLWZiY2MtNDAwMC05NjZkLWFmNWRiNWRiMDdmNyJ9XQ== + + 7e27c87b9f34792e3cc014741fc61876 + + + 1679679205932 + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9LHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyNDEuNjE4NjIwNTM1NzkwM31d + + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyNDEuNjE4NjIwNTM1NzkwM30seyJ4IjoxMDMuNzMyNDQ2NjQxMTUyODUsInkiOjIwNS44MDQwMjk5MTM4MDY1N31d + + e2f90e5e0ae7e2bfc7b087f5bc977a68 + + + 1679679211535 + + DEL_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLCJ0YXJnZXRJRCI6ImIxMTkzYzNmLWVkYzItNDFmZi1hMzFkLTEzNjA2ZjQ0YWU1ZSIsImxhYmVsIjoiUEMiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsImJhY2tncm91bmRDb2xvciI6bnVsbCwic2hhcGUiOiJzb2xpZCJ9LCJpZCI6ImNkNjdjNzg0LTI0OWQtNDk4My1hMzdjLWM0NmMyZWI4OGRkMiJ9XQ== + + 02b9b27f4f51913eb5072fd8d49201da + + + 1679679230448 + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiQ1AiLHRydWVd + + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiVSIsdHJ1ZV0= + + c0fea71530873d797b4fcf7bc9f31b62 + + + 1679679244531 + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiVSIsdHJ1ZV0= + + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiQ1UiLHRydWVd + + 427377cf4540edc7c89dbb46d3870631 + + + 1679679254340 + + UPDATE_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiUEMiLHRydWVd + + + UPDATE_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiUFlNIix0cnVlXQ== + + 6d04014b900a14ae41da1c3b0232f1a6 + + + \ No newline at end of file diff --git a/nintan/teststim0.graphml b/nintan/teststim0.graphml new file mode 100644 index 0000000..ce9eff3 --- /dev/null +++ b/nintan/teststim0.graphml @@ -0,0 +1,185 @@ + + + + + + + + + + + + CZ:cstim0.py + + + + + + + + + + + PZ:pstim0.py + + + + + + + + + + CU + + + + + + + + + + + + PYM + + + + + + + + 1679679128844 + + DEL_NODE + WyJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiXQ== + + + ADD_NODE + WyJDWjpjc3RpbS5weSIseyJ3aWR0aCI6MTA0LCJoZWlnaHQiOjUwLCJzaGFwZSI6InJlY3RhbmdsZSIsIm9wYWNpdHkiOjEsImJhY2tncm91bmRDb2xvciI6IiNmZmNjMDAiLCJib3JkZXJDb2xvciI6IiMwMDAiLCJib3JkZXJXaWR0aCI6MX0sIm9yZGluIix7IngiOjEwMCwieSI6MTAwfSx7fSwiYjExOTNjM2YtZWRjMi00MWZmLWEzMWQtMTM2MDZmNDRhZTVlIl0= + + 2e86d4fed8aafe8ef09f1cf40708efba + + + 1679679163391 + + DEL_NODE + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiXQ== + + + ADD_NODE + WyJQWjpwc3RpbS5weSIseyJ3aWR0aCI6MTA0LCJoZWlnaHQiOjUwLCJzaGFwZSI6InJlY3RhbmdsZSIsIm9wYWNpdHkiOjEsImJhY2tncm91bmRDb2xvciI6IiNmZmNjMDAiLCJib3JkZXJDb2xvciI6IiMwMDAiLCJib3JkZXJXaWR0aCI6MX0sIm9yZGluIix7IngiOjEwMy43MzI0NDY2NDExNTI4NSwieSI6MjQxLjYxODYyMDUzNTc5MDN9LHt9LCJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiXQ== + + 2feb956b0a2b0ced965fd91f629e0b76 + + + 1679679171029 + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTEwLCJ5IjoxMTB9LHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9XQ== + + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9LHsieCI6MTEwLCJ5IjoxMTB9XQ== + + 0f3b77449604c51ef9be645ae0d7d757 + + + 1679679176150 + + DEL_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLCJ0YXJnZXRJRCI6ImEyNDU1ZTBjLWRiMDMtNGFiNy04M2M2LTZlYmUwNjI3YzhkOCIsImxhYmVsIjoiQ1AiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsImJhY2tncm91bmRDb2xvciI6bnVsbCwic2hhcGUiOiJzb2xpZCJ9LCJpZCI6IjA5OWM4MTUyLWZiY2MtNDAwMC05NjZkLWFmNWRiNWRiMDdmNyJ9XQ== + + 7e27c87b9f34792e3cc014741fc61876 + + + 1679679205932 + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9LHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyNDEuNjE4NjIwNTM1NzkwM31d + + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyNDEuNjE4NjIwNTM1NzkwM30seyJ4IjoxMDMuNzMyNDQ2NjQxMTUyODUsInkiOjIwNS44MDQwMjk5MTM4MDY1N31d + + e2f90e5e0ae7e2bfc7b087f5bc977a68 + + + 1679679211535 + + DEL_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLCJ0YXJnZXRJRCI6ImIxMTkzYzNmLWVkYzItNDFmZi1hMzFkLTEzNjA2ZjQ0YWU1ZSIsImxhYmVsIjoiUEMiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsImJhY2tncm91bmRDb2xvciI6bnVsbCwic2hhcGUiOiJzb2xpZCJ9LCJpZCI6ImNkNjdjNzg0LTI0OWQtNDk4My1hMzdjLWM0NmMyZWI4OGRkMiJ9XQ== + + 02b9b27f4f51913eb5072fd8d49201da + + + 1679679230448 + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiQ1AiLHRydWVd + + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiVSIsdHJ1ZV0= + + c0fea71530873d797b4fcf7bc9f31b62 + + + 1679679244531 + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiVSIsdHJ1ZV0= + + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiQ1UiLHRydWVd + + 427377cf4540edc7c89dbb46d3870631 + + + 1679679254340 + + UPDATE_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiUEMiLHRydWVd + + + UPDATE_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiUFlNIix0cnVlXQ== + + 6d04014b900a14ae41da1c3b0232f1a6 + + + 1679681258968 + + UPDATE_NODE + WyJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJDWjpjc3RpbS5weSIsdHJ1ZV0= + + + UPDATE_NODE + WyJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLHsid2lkdGgiOjExMywiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJDWjpjc3RpbTAucHkiLHRydWVd + + f2d618f2115bdf04e91fd5c85bdbc85b + + + 1679681290308 + + UPDATE_NODE + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJQWjpwc3RpbS5weSIsdHJ1ZV0= + + + UPDATE_NODE + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsid2lkdGgiOjExMywiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJQWjpwc3RpbTAucHkiLHRydWVd + + 7bcb667001c20e81dae72339b87abee6 + + + \ No newline at end of file diff --git a/nintan/teststimacq.graphml b/nintan/teststimacq.graphml new file mode 100644 index 0000000..1337649 --- /dev/null +++ b/nintan/teststimacq.graphml @@ -0,0 +1,280 @@ + + + + + + + + + + + + CZ:cstim.py + + + + + + + + + + + PZ:pstim.py + + + + + + + + + + + AZ:pacq.py + + + + + + + + + + CU + + + + + + + + + + + + PYM + + + + + + + + + + + + AYM + + + + + + + + 1679679128844 + + DEL_NODE + WyJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiXQ== + + + ADD_NODE + WyJDWjpjc3RpbS5weSIseyJ3aWR0aCI6MTA0LCJoZWlnaHQiOjUwLCJzaGFwZSI6InJlY3RhbmdsZSIsIm9wYWNpdHkiOjEsImJhY2tncm91bmRDb2xvciI6IiNmZmNjMDAiLCJib3JkZXJDb2xvciI6IiMwMDAiLCJib3JkZXJXaWR0aCI6MX0sIm9yZGluIix7IngiOjEwMCwieSI6MTAwfSx7fSwiYjExOTNjM2YtZWRjMi00MWZmLWEzMWQtMTM2MDZmNDRhZTVlIl0= + + 2e86d4fed8aafe8ef09f1cf40708efba + + + 1679679163391 + + DEL_NODE + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiXQ== + + + ADD_NODE + WyJQWjpwc3RpbS5weSIseyJ3aWR0aCI6MTA0LCJoZWlnaHQiOjUwLCJzaGFwZSI6InJlY3RhbmdsZSIsIm9wYWNpdHkiOjEsImJhY2tncm91bmRDb2xvciI6IiNmZmNjMDAiLCJib3JkZXJDb2xvciI6IiMwMDAiLCJib3JkZXJXaWR0aCI6MX0sIm9yZGluIix7IngiOjEwMy43MzI0NDY2NDExNTI4NSwieSI6MjQxLjYxODYyMDUzNTc5MDN9LHt9LCJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiXQ== + + 80c0f78366d87d0e9cb4a9f779ef910d + + + 1679679171029 + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTEwLCJ5IjoxMTB9LHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9XQ== + + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9LHsieCI6MTEwLCJ5IjoxMTB9XQ== + + c57e6b6829d726b5f03a833b44307338 + + + 1679679176150 + + DEL_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLCJ0YXJnZXRJRCI6ImEyNDU1ZTBjLWRiMDMtNGFiNy04M2M2LTZlYmUwNjI3YzhkOCIsImxhYmVsIjoiQ1AiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsImJhY2tncm91bmRDb2xvciI6bnVsbCwic2hhcGUiOiJzb2xpZCJ9LCJpZCI6IjA5OWM4MTUyLWZiY2MtNDAwMC05NjZkLWFmNWRiNWRiMDdmNyJ9XQ== + + 2b810795ac0dbd48c4b6260f5104c3b1 + + + 1679679205932 + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9LHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyNDEuNjE4NjIwNTM1NzkwM31d + + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyNDEuNjE4NjIwNTM1NzkwM30seyJ4IjoxMDMuNzMyNDQ2NjQxMTUyODUsInkiOjIwNS44MDQwMjk5MTM4MDY1N31d + + 18d729b7e03e83e84b6fbd286d788f71 + + + 1679679211535 + + DEL_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLCJ0YXJnZXRJRCI6ImIxMTkzYzNmLWVkYzItNDFmZi1hMzFkLTEzNjA2ZjQ0YWU1ZSIsImxhYmVsIjoiUEMiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsImJhY2tncm91bmRDb2xvciI6bnVsbCwic2hhcGUiOiJzb2xpZCJ9LCJpZCI6ImNkNjdjNzg0LTI0OWQtNDk4My1hMzdjLWM0NmMyZWI4OGRkMiJ9XQ== + + e08334b92279b7c8a1863601555d0c32 + + + 1679679230448 + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiQ1AiLHRydWVd + + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiVSIsdHJ1ZV0= + + d9ee24f85d386f27731edf62627e54a7 + + + 1679679244531 + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiVSIsdHJ1ZV0= + + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiQ1UiLHRydWVd + + 5dc0d5c06a55c52b36813323f7847b41 + + + 1679679254340 + + UPDATE_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiUEMiLHRydWVd + + + UPDATE_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiUFlNIix0cnVlXQ== + + 6741405b1346bb7d4696e6f43d8dd767 + + + 1680063133865 + + DEL_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiXQ== + + + ADD_NODE + WyJBUTpwYWNxLnB5Iix7IndpZHRoIjoxMDQsImhlaWdodCI6NTAsInNoYXBlIjoicmVjdGFuZ2xlIiwib3BhY2l0eSI6MSwiYmFja2dyb3VuZENvbG9yIjoiI2ZmY2MwMCIsImJvcmRlckNvbG9yIjoiIzAwMCIsImJvcmRlcldpZHRoIjoxfSwib3JkaW4iLHsieCI6MzM5LCJ5IjoxNTZ9LHt9LCJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiXQ== + + ef796b8657d7fcf6afef8fa7aac0ffff + + + 1680063141667 + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6MTEwLCJ5IjoxMTB9LHsieCI6Mjc2LCJ5IjoxNTR9XQ== + + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6Mjc2LCJ5IjoxNTR9LHsieCI6MTEwLCJ5IjoxMTB9XQ== + + a98afef4b19f14d140b7af8fa63db087 + + + 1680063155805 + + DEL_EDGE + WyIxM2I4NWVmMS01YjM2LTQ0MmEtYmYxZC1lMGY1YTE5Y2IwNWUiXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLCJ0YXJnZXRJRCI6ImUwYzM1ZmE2LTQ4NWMtNGIyOS1hNTM5LTBiZmFjMDBlZDMyMCIsImlkIjoiMTNiODVlZjEtNWIzNi00NDJhLWJmMWQtZTBmNWExOWNiMDVlIn1d + + 778e62b28db4b9ca2eb333236bba9b74 + + + 1680063168225 + + ADD_EDGE + W3sibGFiZWwiOiJQWU0iLCJzb3VyY2UiOiJlZTUxZWM5NC1hZTZkLTQ3NmEtYjlhOC1kNmFmNjg5ZmIxMjUiLCJ0YXJnZXQiOiJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsInNoYXBlIjoic29saWQifSwiYmVuZERhdGEiOnsiYmVuZERpc3RhbmNlIjoyMi45NTU5ODkxMTI2NTAxNjIsImJlbmRXZWlnaHQiOjAuNTA4MDY3NzAxOTg3NDI4NSwiYmVuZFBvaW50Ijp7IngiOjEzNC4xMDQxNTA3MzU2NTM3MiwieSI6MTUyLjgxNzM2MzIzMzU5ODM3fX0sInNvdXJjZUlEIjoiYTI0NTVlMGMtZGIwMy00YWI3LTgzYzYtNmViZTA2MjdjOGQ4IiwidGFyZ2V0SUQiOiJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLCJ0eXBlIjoib3JkaW4iLCJpZCI6IjZjNDU5ZThkLTFkZWQtNDhkNy05ZTIyLWNiMGE2ZTc5MjkxYiJ9XQ== + + + DEL_EDGE + WyI2YzQ1OWU4ZC0xZGVkLTQ4ZDctOWUyMi1jYjBhNmU3OTI5MWIiXQ== + + b3482e49055a81731f7b95b7d0ef5da8 + + + 1680063177212 + + DEL_EDGE + WyIzNmUyMTE3Ny04YzdhLTQ4YjQtYTE2ZS1mYTJhOWUxZjk4ZjciXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLCJ0YXJnZXRJRCI6ImIxMTkzYzNmLWVkYzItNDFmZi1hMzFkLTEzNjA2ZjQ0YWU1ZSIsImxhYmVsIjoiQVlNIiwic3R5bGUiOnsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiaWQiOiIzNmUyMTE3Ny04YzdhLTQ4YjQtYTE2ZS1mYTJhOWUxZjk4ZjcifV0= + + b9ec4eaa5bead6d881191cf1cb501643 + + + 1680063187427 + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6Mjc2LCJ5IjoxNTR9LHsieCI6MzM5LCJ5IjoxNTZ9XQ== + + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6MzM5LCJ5IjoxNTZ9LHsieCI6Mjc2LCJ5IjoxNTR9XQ== + + ed4a57e0e6dfed4c9345249e55f7b056 + + + 1680063190935 + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBUTpwYWNxLnB5Iix0cnVlXQ== + + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjoiLHRydWVd + + c60aa480e8b8bf1960556dc08773d337 + + + 1680063200154 + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjoiLHRydWVd + + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjpwYWNxLnB5Iix0cnVlXQ== + + c15d3a2174783f98c1d0953ee0a1bb37 + + + \ No newline at end of file diff --git a/nintan/teststimacq0.graphml b/nintan/teststimacq0.graphml new file mode 100644 index 0000000..729c823 --- /dev/null +++ b/nintan/teststimacq0.graphml @@ -0,0 +1,328 @@ + + + + + + + + + + + + CZ:cstim.py + + + + + + + + + + + PZ:pstim0.py + + + + + + + + + + + AZ:pacq0.py + + + + + + + + + + CU + + + + + + + + + + + + PYM + + + + + + + + + + + + AYM + + + + + + + + 1679679128844 + + DEL_NODE + WyJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiXQ== + + + ADD_NODE + WyJDWjpjc3RpbS5weSIseyJ3aWR0aCI6MTA0LCJoZWlnaHQiOjUwLCJzaGFwZSI6InJlY3RhbmdsZSIsIm9wYWNpdHkiOjEsImJhY2tncm91bmRDb2xvciI6IiNmZmNjMDAiLCJib3JkZXJDb2xvciI6IiMwMDAiLCJib3JkZXJXaWR0aCI6MX0sIm9yZGluIix7IngiOjEwMCwieSI6MTAwfSx7fSwiYjExOTNjM2YtZWRjMi00MWZmLWEzMWQtMTM2MDZmNDRhZTVlIl0= + + 2e86d4fed8aafe8ef09f1cf40708efba + + + 1679679163391 + + DEL_NODE + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiXQ== + + + ADD_NODE + WyJQWjpwc3RpbS5weSIseyJ3aWR0aCI6MTA0LCJoZWlnaHQiOjUwLCJzaGFwZSI6InJlY3RhbmdsZSIsIm9wYWNpdHkiOjEsImJhY2tncm91bmRDb2xvciI6IiNmZmNjMDAiLCJib3JkZXJDb2xvciI6IiMwMDAiLCJib3JkZXJXaWR0aCI6MX0sIm9yZGluIix7IngiOjEwMy43MzI0NDY2NDExNTI4NSwieSI6MjQxLjYxODYyMDUzNTc5MDN9LHt9LCJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiXQ== + + 80c0f78366d87d0e9cb4a9f779ef910d + + + 1679679171029 + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTEwLCJ5IjoxMTB9LHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9XQ== + + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9LHsieCI6MTEwLCJ5IjoxMTB9XQ== + + c57e6b6829d726b5f03a833b44307338 + + + 1679679176150 + + DEL_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLCJ0YXJnZXRJRCI6ImEyNDU1ZTBjLWRiMDMtNGFiNy04M2M2LTZlYmUwNjI3YzhkOCIsImxhYmVsIjoiQ1AiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsImJhY2tncm91bmRDb2xvciI6bnVsbCwic2hhcGUiOiJzb2xpZCJ9LCJpZCI6IjA5OWM4MTUyLWZiY2MtNDAwMC05NjZkLWFmNWRiNWRiMDdmNyJ9XQ== + + 2b810795ac0dbd48c4b6260f5104c3b1 + + + 1679679205932 + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyMDUuODA0MDI5OTEzODA2NTd9LHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyNDEuNjE4NjIwNTM1NzkwM31d + + + SET_POS + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsieCI6MTAzLjczMjQ0NjY0MTE1Mjg1LCJ5IjoyNDEuNjE4NjIwNTM1NzkwM30seyJ4IjoxMDMuNzMyNDQ2NjQxMTUyODUsInkiOjIwNS44MDQwMjk5MTM4MDY1N31d + + 18d729b7e03e83e84b6fbd286d788f71 + + + 1679679211535 + + DEL_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLCJ0YXJnZXRJRCI6ImIxMTkzYzNmLWVkYzItNDFmZi1hMzFkLTEzNjA2ZjQ0YWU1ZSIsImxhYmVsIjoiUEMiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsImJhY2tncm91bmRDb2xvciI6bnVsbCwic2hhcGUiOiJzb2xpZCJ9LCJpZCI6ImNkNjdjNzg0LTI0OWQtNDk4My1hMzdjLWM0NmMyZWI4OGRkMiJ9XQ== + + e08334b92279b7c8a1863601555d0c32 + + + 1679679230448 + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiQ1AiLHRydWVd + + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiVSIsdHJ1ZV0= + + d9ee24f85d386f27731edf62627e54a7 + + + 1679679244531 + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiVSIsdHJ1ZV0= + + + UPDATE_EDGE + WyIwOTljODE1Mi1mYmNjLTQwMDAtOTY2ZC1hZjVkYjVkYjA3ZjciLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiQ1UiLHRydWVd + + 5dc0d5c06a55c52b36813323f7847b41 + + + 1679679254340 + + UPDATE_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiUEMiLHRydWVd + + + UPDATE_EDGE + WyJjZDY3Yzc4NC0yNDlkLTQ5ODMtYTM3Yy1jNDZjMmViODhkZDIiLHsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiUFlNIix0cnVlXQ== + + 6741405b1346bb7d4696e6f43d8dd767 + + + 1680063133865 + + DEL_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiXQ== + + + ADD_NODE + WyJBUTpwYWNxLnB5Iix7IndpZHRoIjoxMDQsImhlaWdodCI6NTAsInNoYXBlIjoicmVjdGFuZ2xlIiwib3BhY2l0eSI6MSwiYmFja2dyb3VuZENvbG9yIjoiI2ZmY2MwMCIsImJvcmRlckNvbG9yIjoiIzAwMCIsImJvcmRlcldpZHRoIjoxfSwib3JkaW4iLHsieCI6MzM5LCJ5IjoxNTZ9LHt9LCJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiXQ== + + 3287a038f8fe444dee54a3810ee43e4d + + + 1680063141667 + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6MTEwLCJ5IjoxMTB9LHsieCI6Mjc2LCJ5IjoxNTR9XQ== + + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6Mjc2LCJ5IjoxNTR9LHsieCI6MTEwLCJ5IjoxMTB9XQ== + + f7d58daaa5012b5681a7083b83a4631b + + + 1680063155805 + + DEL_EDGE + WyIxM2I4NWVmMS01YjM2LTQ0MmEtYmYxZC1lMGY1YTE5Y2IwNWUiXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLCJ0YXJnZXRJRCI6ImUwYzM1ZmE2LTQ4NWMtNGIyOS1hNTM5LTBiZmFjMDBlZDMyMCIsImlkIjoiMTNiODVlZjEtNWIzNi00NDJhLWJmMWQtZTBmNWExOWNiMDVlIn1d + + cc6959d442babdc676db4b9c10832c42 + + + 1680063168225 + + ADD_EDGE + W3sibGFiZWwiOiJQWU0iLCJzb3VyY2UiOiJlZTUxZWM5NC1hZTZkLTQ3NmEtYjlhOC1kNmFmNjg5ZmIxMjUiLCJ0YXJnZXQiOiJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLCJzdHlsZSI6eyJ0aGlja25lc3MiOjEsInNoYXBlIjoic29saWQifSwiYmVuZERhdGEiOnsiYmVuZERpc3RhbmNlIjoyMi45NTU5ODkxMTI2NTAxNjIsImJlbmRXZWlnaHQiOjAuNTA4MDY3NzAxOTg3NDI4NSwiYmVuZFBvaW50Ijp7IngiOjEzNC4xMDQxNTA3MzU2NTM3MiwieSI6MTUyLjgxNzM2MzIzMzU5ODM3fX0sInNvdXJjZUlEIjoiYTI0NTVlMGMtZGIwMy00YWI3LTgzYzYtNmViZTA2MjdjOGQ4IiwidGFyZ2V0SUQiOiJiMTE5M2MzZi1lZGMyLTQxZmYtYTMxZC0xMzYwNmY0NGFlNWUiLCJ0eXBlIjoib3JkaW4iLCJpZCI6IjZjNDU5ZThkLTFkZWQtNDhkNy05ZTIyLWNiMGE2ZTc5MjkxYiJ9XQ== + + + DEL_EDGE + WyI2YzQ1OWU4ZC0xZGVkLTQ4ZDctOWUyMi1jYjBhNmU3OTI5MWIiXQ== + + 686c147a5abc46f1df084baa5e2cf814 + + + 1680063177212 + + DEL_EDGE + WyIzNmUyMTE3Ny04YzdhLTQ4YjQtYTE2ZS1mYTJhOWUxZjk4ZjciXQ== + + + ADD_EDGE + W3sic291cmNlSUQiOiJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLCJ0YXJnZXRJRCI6ImIxMTkzYzNmLWVkYzItNDFmZi1hMzFkLTEzNjA2ZjQ0YWU1ZSIsImxhYmVsIjoiQVlNIiwic3R5bGUiOnsidGhpY2tuZXNzIjoxLCJiYWNrZ3JvdW5kQ29sb3IiOm51bGwsInNoYXBlIjoic29saWQifSwiaWQiOiIzNmUyMTE3Ny04YzdhLTQ4YjQtYTE2ZS1mYTJhOWUxZjk4ZjcifV0= + + edb67f19b4a7824d05206aa4e881a1a6 + + + 1680063187427 + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6Mjc2LCJ5IjoxNTR9LHsieCI6MzM5LCJ5IjoxNTZ9XQ== + + + SET_POS + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsieCI6MzM5LCJ5IjoxNTZ9LHsieCI6Mjc2LCJ5IjoxNTR9XQ== + + 66858450ca671faf70f4c4405304cabc + + + 1680063190935 + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBUTpwYWNxLnB5Iix0cnVlXQ== + + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjoiLHRydWVd + + 3f0ebff9c7be28e0d2f31fd458269284 + + + 1680063200154 + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjoiLHRydWVd + + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwic2hhcGUiOiJyZWN0YW5nbGUiLCJvcGFjaXR5IjoxLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjpwYWNxLnB5Iix0cnVlXQ== + + 06c7aa1eb3de8407b009e0837f191c3f + + + 1680112486999 + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjpwYWNxLnB5Iix0cnVlXQ== + + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjExMywiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjpwbG90eW0ucHkiLHRydWVd + + 1e1c7a613c4ff82dadf9f654081eacc7 + + + 1680112660989 + + UPDATE_NODE + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsid2lkdGgiOjEwNCwiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJQWjpwc3RpbS5weSIsdHJ1ZV0= + + + UPDATE_NODE + WyJhMjQ1NWUwYy1kYjAzLTRhYjctODNjNi02ZWJlMDYyN2M4ZDgiLHsid2lkdGgiOjExMywiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJQWjpwc3RpbTAucHkiLHRydWVd + + da27b84084e25fd34107340e91be8c25 + + + 1680114578248 + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjExMywiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjpwbG90eW0ucHkiLHRydWVd + + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjExMywiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjpwYWNxLnB5Iix0cnVlXQ== + + c2a34249b2e3bf3a8bf4d0034460e9cc + + + 1680456259947 + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjExMywiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjpwYWNxLnB5Iix0cnVlXQ== + + + UPDATE_NODE + WyJlMGMzNWZhNi00ODVjLTRiMjktYTUzOS0wYmZhYzAwZWQzMjAiLHsid2lkdGgiOjExMywiaGVpZ2h0Ijo1MCwib3BhY2l0eSI6MSwic2hhcGUiOiJyZWN0YW5nbGUiLCJiYWNrZ3JvdW5kQ29sb3IiOiIjZmZjYzAwIiwiYm9yZGVyQ29sb3IiOiIjMDAwIiwiYm9yZGVyV2lkdGgiOjF9LCJBWjpwYWNxMC5weSIsdHJ1ZV0= + + 30341e0ad7b3b0d4a0602da68ac4ec18 + + + \ No newline at end of file