问:
How to update search parameters within a for loop
How can i alter the if tweets_per_day == 100 if statement so that when the for loop does its next iteration, the day variable is equal to the prior day? For example, here is what I wish to do:

On the first iteration of the for loop, 100 tweets created within the specified parameters will be appended to the all_tweets list. Currently working properly

Once 100 tweets have been appended, the day count will be updated by 1. Currently working properly

Within the mentioned if statement, as 100 tweets for the day have been appended, the search parameters for the tweets should be updated, by only displaying tweets which were created 1 day less than the previous day. Not working

The for loop restarts with the previous parameters in mind

```<code>from datetime import datetime, timedelta
import pandas as pd
import sys
import numpy as np
from datetime import datetime, timedelta, time
import tweepy
from workalendar.usa import NewYork
import re
import pytz
import configparser

# Read Configs
config = configparser.ConfigParser()
config.read('config.ini')

# Twitter API Credentials
api_key = config['twitter']['api_key']
api_key_secret = config['twitter']['api_key_secret']
access_token = config['twitter']['access_token']
access_token_secret = config['twitter']['access_token_secret']

# Authentication
auth = tweepy.OAuthHandler(api_key, api_key_secret)
auth.set_access_token(access_token, access_token_secret)

# Make an API object
api = tweepy.API(auth)

stock = input('Enter a stock symbol: ').upper()
stock = '$' + stock  # Convert user input to Twitter cashtag
print(stock)

start_date = datetime.now().date()

search_parameters = {
    'q': stock,
    'lang': 'en',
    'count': 100,
    'until': start_date,
    'tweet_mode': 'ext'
}

cursor = tweepy.Cursor(api.search_tweets, **search_parameters)

# Create a list of market holidays, where the stock exchange is closed
cal = NewYork()
cal.holidays(2023)

# Create a dataframe of stock market holidays
holiday_df = pd.DataFrame(cal.holidays(2023), columns=['Date', 'Holiday'])
holiday_df = holiday_df.drop([0, 3, 4, 9, 10, 11, 12])  # Remove non-market-holidays

# Add additional market holidays
holiday_df.loc[9] = ['2023-04-07', 'Good Friday']
holiday_df.loc[10] = ['2023-06-19', 'Juneteenth']

holiday_df['Date'] = pd.to_datetime(holiday_df['Date'])
tweets_per_day = 0
day_count = 0
dates = []  # empty list to store the dates of appended tweets
all_tweets = []  # empty list to store all tweets being used

tweet_iterator = cursor.items(limit=1000)

for tweet in cursor.items(limit=10000):
    day = tweet.created_at
    print(f'Start of for loop day value: {day}')
    tweet_date = pd.to_datetime(day.date().strftime('%Y-%m-%d'))
    # Only add tweets which were made before market open on weekdays
    if day.time() < time(hour=9, minute=30) and day.weekday() < 5:
        if not holiday_df['Date'].eq(tweet_date).any():
            print(f'Tweet date {tweet.created_at.date()}, day date {day.date()}')
            while tweets_per_day < 100:
                if tweet.created_at.date() != day.date():  # If the day changes before 100 tweets, update day count
                    day_count += 1
                    tweets_per_day = 0
                    print('day != block')
                    break
                all_tweets.append(tweet.text)
                tweets_per_day += 1
                dates.append(tweet.created_at.date())
                print(f'Appended Tweet date: {tweet.created_at}')
                print(f'Tweets per day: {tweets_per_day}')
                tweet = next(tweet_iterator)
            if tweets_per_day == 100:
                day_count += 1
                search_parameters['until'] -= timedelta(days=1)
                cursor = tweepy.Cursor(api.search_tweets, **search_parameters)  # create a new Cursor with the updated search parameters
                tweet_iterator = cursor.items(limit=1000)  # update the tweet iterator with the new Cursor
                tweets_per_day = 0
    if day_count >= 5:
        print(f'Day count: {day_count}')
        break
</code>```

Body:
How can i alter the if tweets_per_day == 100 if statement so that when the for loop does its next iteration, the day variable is equal to the prior day? For example, here is what I wish to do:

On the first iteration of the for loop, 100 tweets created within the specified parameters will be appended to the all_tweets list. Currently working properly

Once 100 tweets have been appended, the day count will be updated by 1. Currently working properly

Within the mentioned if statement, as 100 tweets for the day have been appended, the search parameters for the tweets should be updated, by only displaying tweets which were created 1 day less than the previous day. Not working

The for loop restarts with the previous parameters in mind

from datetime import datetime, timedelta
import pandas as pd
import sys
import numpy as np
from datetime import datetime, timedelta, time
import tweepy
from workalendar.usa import NewYork
import re
import pytz
import configparser

# Read Configs
config = configparser.ConfigParser()
config.read('config.ini')

# Twitter API Credentials
api_key = config['twitter']['api_key']
api_key_secret = config['twitter']['api_key_secret']
access_token = config['twitter']['access_token']
access_token_secret = config['twitter']['access_token_secret']

# Authentication
auth = tweepy.OAuthHandler(api_key, api_key_secret)
auth.set_access_token(access_token, access_token_secret)

# Make an API object
api = tweepy.API(auth)

stock = input('Enter a stock symbol: ').upper()
stock = '$' + stock  # Convert user input to Twitter cashtag
print(stock)

start_date = datetime.now().date()

search_parameters = {
    'q': stock,
    'lang': 'en',
    'count': 100,
    'until': start_date,
    'tweet_mode': 'ext'
}

cursor = tweepy.Cursor(api.search_tweets, **search_parameters)

# Create a list of market holidays, where the stock exchange is closed
cal = NewYork()
cal.holidays(2023)

# Create a dataframe of stock market holidays
holiday_df = pd.DataFrame(cal.holidays(2023), columns=['Date', 'Holiday'])
holiday_df = holiday_df.drop([0, 3, 4, 9, 10, 11, 12])  # Remove non-market-holidays

# Add additional market holidays
holiday_df.loc[9] = ['2023-04-07', 'Good Friday']
holiday_df.loc[10] = ['2023-06-19', 'Juneteenth']

holiday_df['Date'] = pd.to_datetime(holiday_df['Date'])
tweets_per_day = 0
day_count = 0
dates = []  # empty list to store the dates of appended tweets
all_tweets = []  # empty list to store all tweets being used

tweet_iterator = cursor.items(limit=1000)

for tweet in cursor.items(limit=10000):
    day = tweet.created_at
    print(f'Start of for loop day value: {day}')
    tweet_date = pd.to_datetime(day.date().strftime('%Y-%m-%d'))
    # Only add tweets which were made before market open on weekdays
    if day.time() < time(hour=9, minute=30) and day.weekday() < 5:
        if not holiday_df['Date'].eq(tweet_date).any():
            print(f'Tweet date {tweet.created_at.date()}, day date {day.date()}')
            while tweets_per_day < 100:
                if tweet.created_at.date() != day.date():  # If the day changes before 100 tweets, update day count
                    day_count += 1
                    tweets_per_day = 0
                    print('day != block')
                    break
                all_tweets.append(tweet.text)
                tweets_per_day += 1
                dates.append(tweet.created_at.date())
                print(f'Appended Tweet date: {tweet.created_at}')
                print(f'Tweets per day: {tweets_per_day}')
                tweet = next(tweet_iterator)
            if tweets_per_day == 100:
                day_count += 1
                search_parameters['until'] -= timedelta(days=1)
                cursor = tweepy.Cursor(api.search_tweets, **search_parameters)  # create a new Cursor with the updated search parameters
                tweet_iterator = cursor.items(limit=1000)  # update the tweet iterator with the new Cursor
                tweets_per_day = 0
    if day_count >= 5:
        print(f'Day count: {day_count}')
        break


来源: stackexchange

问:
Code coverage for integration test by jest and nyc always return 0% for statements and lines
I'm trying to do code coverage for our Jest integration tests.
The tests directory is inside some sub-directory inside the server project with standalone package.json and configurations.
The services and libs that need to cover are located in the main project root directory, that mean outside the tests sub-directory.

When I've tried to it by nyc is able to include the required directories outside the tests dir but no real coverage are return in the report.

When I've tried to id by the --coverage flag in Jest, It's not able to access outside the tests dir, even when adding rootDir option inside the configuration file, it just make a mess in the project.

I've also tried to execute nyc together with the api-gateway launching and together with the services launching but it didn't change the results as well.

The project architecture is something like the following -->

```<code>server-project root
  .nyc_output
  _coverage_
  services
  libs
  src
  api-gateway
  test
  - src
   - integration-tests
     -  test.ts
     -  ...
  - jest.config.ts
  - jest-integration.config.ts
  - package.json
  package.json

</code>```

Related versions:

```<code>Node v14.18.1
npm 6.14.15
pnpm 6.9.1

"istanbul-reports": "^3.1.5",
"jest": "^26.6.3",
"@types/jest": "^26.0.18",
"@types/node": "13.7.1",
"babel-plugin-istanbul": "^6.1.1",
"nyc": "^15.1.0",
"ts-jest": "^26.4.4",
"ts-node": "^9.1.1",
"typescript": "^4.1.2"
</code>```

The script below contains nyc together with jest - non of them work as expected:

```<code>"test:integration:coverage": "nyc --cwd='../' --exclude-after-remapjest=false --reporter=lcov --reporter=text pnpm run test:integration -- --coverage --collectCoverageFrom='./../services/**/src/*.ts'",
</code>```

It's located inside test/package.json and launchd by pnpm

nyc configuration inside package.json (project root) -->

```<code>  "nyc": {
    "extends": "@istanbuljs/nyc-config-typescript",
    "require": "@babel/register",
    "check-coverage": true,
    "all": true,
    "cache": true,
    "sourceMap": false,
    "instrument": true,
    "lines": 90,
    "branches": 90,
    "functions": 90,
    "statements": 90,
    "reporter": [
      "text-summary",
      "lcov",
      "text"
    ],
    "report-dir": "coverage",
    "include": [
      "services/**/src/*.ts",
      "api-gateway/src/*.ts",
      "libs/**/src/*.ts"
    ],
    "exclude": [
      "**/test/**",
      "**/*.d.ts"
    ],
    "extension": [
      ".ts",
      ".tsx"
    ],
    "temp-dir": ".nyc_output",
    "excludeNodeModules": true,
    "source-map": true,
    "produce-source-map": true
  }
</code>```

Jest configuration iside test/jest-integration.config.ts (extends to the main jest.config.ts file) -->

```<code>    // eslint-disable-next-line @typescript-eslint/no-var-requires
const baseConfig = require('./jest.config');
const base = '**/integration-tests/services';
const setupDir = './src/tests/integration-tests/setup';
module.exports = {
  ...baseConfig,
  testMatch: [
    ...[
      'abtests/*.test.ts',
       'moretests/*.test.ts',
  ],
  globalSetup: `${setupDir}/jest-integration-setup.ts`,
  globalTeardown: `${setupDir}/jest-integration-teardown.ts`,
};
</code>```

Output results:

```<code>  at src/tests/integration-tests/services/abtests/abtest.test.ts:18:13
</code>```

PASS  src/tests/integration-tests/services/abtests/abtest.test.ts
abtests
✓ abtests params in me query (300 ms)
✓ override existing test (110 ms)
✓ create a new test with value (109 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |       0 |        0 |       0 |       0 |

----------|---------|----------|---------|---------|-------------------

```<code>    Failed to write coverage reports:
    ERROR: TypeError: Cannot convert undefined or null to object
    STACK: TypeError: Cannot convert undefined or null to object
at Function.getPrototypeOf (<anonymous>)
at Date (/Users/myname/repos/server-project/node_modules/.pnpm/jest-date-mock@1.0.8/node_modules/jest-date-mock/lib/mockDate.js:39:44)
at new HtmlReport (/Users/myname/repos/server-project/node_modules/.pnpm/istanbul-reports@3.0.2/node_modules/istanbul-reports/lib/html/index.js:260:21)
at new LcovReport (/Users/myname/repos/server-project/node_modules/.pnpm/istanbul-reports@3.0.2/node_modules/istanbul-reports/lib/lcov/index.js:14:21)
at Object.create (/Users/myname/repos/server-project/node_modules/.pnpm/istanbul-reports@3.0.2/node_modules/istanbul-reports/index.js:22:16)
at /Users/myname/repos/server-project/node_modules/.pnpm/@jest+reporters@26.6.2/node_modules/@jest/reporters/build/CoverageReporter.js:248:20
at Array.forEach (<anonymous>)
at CoverageReporter.onRunComplete (/Users/myname/repos/server-project/node_modules/.pnpm/@jest+reporters@26.6.2/node_modules/@jest/reporters/build/CoverageReporter.js:240:25)
at ReporterDispatcher.onRunComplete (/Users/myname/repos/server-project/node_modules/.pnpm/@jest+core@26.6.3/node_modules/@jest/core/build/ReporterDispatcher.js:88:9)
at TestScheduler.scheduleTests (/Users/myname/repos/server-project/node_modules/.pnpm/@jest+core@26.6.3/node_modules/@jest/core/build/TestScheduler.js:350:5)
at runJest (/Users/myname/repos/server-project/node_modules/.pnpm/@jest+core@26.6.3/node_modules/@jest/core/build/runJest.js:376:19)
at _run10000 (/Users/myanme/repos/server-project/node_modules/.pnpm/@jest+core@26.6.3/node_modules/@jest/core/build/cli/index.js:416:7)
at runCLI (/Users/myname/repos/server-project/node_modules/.pnpm/@jest+core@26.6.3/node_modules/@jest/core/build/cli/index.js:271:3)
at Object.run (/Users/myname/repos/server-project/node_modules/.pnpm/jest-cli@26.6.3/node_modules/jest-cli/build/cli/index.js:163:37)

</code>```

Test Suites: 2 passed, 2 total
Tests:       1 skipped, 4 passed, 5 total
Snapshots:   0 total
Time:        10.01 s
Ran all test suites.
 report is created on: /Users/myname/repos/server-project/test/html-report/report.html
ERROR: Coverage for lines (0%) does not meet global threshold (90%)
ERROR: Coverage for functions (0%) does not meet global threshold (90%)
ERROR: Coverage for branches (0%) does not meet global threshold (90%)
ERROR: Coverage for statements (0%) does not meet global threshold (90%)
-----------------------------------------|---------|----------|---------|---------|-------------------
File                                     | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------------------------------------|---------|----------|---------|---------|-------------------
All files                                |       0 |        0 |       0 |       0 |

api-gateway/src                         |       0 |        0 |       0 |       0 |

config.ts                              |       0 |      100 |     100 |       0 | 81

main.ts                                |       0 |        0 |       0 |       0 | 11-43

storage.ts                             |       0 |        0 |       0 |       0 | 6-19

libs/apollo-federation-tester/src       |       0 |        0 |       0 |       0 |

index.ts                               |       0 |        0 |       0 |       0 | 17-85

Please your help!
Thanks.

ContentLicense: CC BY-SA 4.0

Body:
I'm trying to do code coverage for our Jest integration tests.
The tests directory is inside some sub-directory inside the server project with standalone package.json and configurations.
The services and libs that need to cover are located in the main project root directory, that mean outside the tests sub-directory.

When I've tried to it by nyc is able to include the required directories outside the tests dir but no real coverage are return in the report.

When I've tried to id by the --coverage flag in Jest, It's not able to access outside the tests dir, even when adding rootDir option inside the configuration file, it just make a mess in the project.

I've also tried to execute nyc together with the api-gateway launching and together with the services launching but it didn't change the results as well.

The project architecture is something like the following -->

server-project root
  .nyc_output
  _coverage_
  services
  libs
  src
  api-gateway
  test
  - src
   - integration-tests
     -  test.ts
     -  ...
  - jest.config.ts
  - jest-integration.config.ts
  - package.json
  package.json

Related versions:

Node v14.18.1
npm 6.14.15
pnpm 6.9.1

"istanbul-reports": "^3.1.5",
"jest": "^26.6.3",
"@types/jest": "^26.0.18",
"@types/node": "13.7.1",
"babel-plugin-istanbul": "^6.1.1",
"nyc": "^15.1.0",
"ts-jest": "^26.4.4",
"ts-node": "^9.1.1",
"typescript": "^4.1.2"

The script below contains nyc together with jest - non of them work as expected:

"test:integration:coverage": "nyc --cwd='../' --exclude-after-remapjest=false --reporter=lcov --reporter=text pnpm run test:integration -- --coverage --collectCoverageFrom='./../services/**/src/*.ts'",

It's located inside test/package.json and launchd by pnpm

nyc configuration inside package.json (project root) -->

  "nyc": {
    "extends": "@istanbuljs/nyc-config-typescript",
    "require": "@babel/register",
    "check-coverage": true,
    "all": true,
    "cache": true,
    "sourceMap": false,
    "instrument": true,
    "lines": 90,
    "branches": 90,
    "functions": 90,
    "statements": 90,
    "reporter": [
      "text-summary",
      "lcov",
      "text"
    ],
    "report-dir": "coverage",
    "include": [
      "services/**/src/*.ts",
      "api-gateway/src/*.ts",
      "libs/**/src/*.ts"
    ],
    "exclude": [
      "**/test/**",
      "**/*.d.ts"
    ],
    "extension": [
      ".ts",
      ".tsx"
    ],
    "temp-dir": ".nyc_output",
    "excludeNodeModules": true,
    "source-map": true,
    "produce-source-map": true
  }

Jest configuration iside test/jest-integration.config.ts (extends to the main jest.config.ts file) -->

    // eslint-disable-next-line @typescript-eslint/no-var-requires
const baseConfig = require('./jest.config');
const base = '**/integration-tests/services';
const setupDir = './src/tests/integration-tests/setup';
module.exports = {
  ...baseConfig,
  testMatch: [
    ...[
      'abtests/*.test.ts',
       'moretests/*.test.ts',
  ],
  globalSetup: `${setupDir}/jest-integration-setup.ts`,
  globalTeardown: `${setupDir}/jest-integration-teardown.ts`,
};

Output results:

  at src/tests/integration-tests/services/abtests/abtest.test.ts:18:13

PASS  src/tests/integration-tests/services/abtests/abtest.test.ts
abtests
✓ abtests params in me query (300 ms)
✓ override existing test (110 ms)
✓ create a new test with value (109 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |       0 |        0 |       0 |       0 |

----------|---------|----------|---------|---------|-------------------

    Failed to write coverage reports:
    ERROR: TypeError: Cannot convert undefined or null to object
    STACK: TypeError: Cannot convert undefined or null to object
at Function.getPrototypeOf (<anonymous>)
at Date (/Users/myname/repos/server-project/node_modules/.pnpm/jest-date-mock@1.0.8/node_modules/jest-date-mock/lib/mockDate.js:39:44)
at new HtmlReport (/Users/myname/repos/server-project/node_modules/.pnpm/istanbul-reports@3.0.2/node_modules/istanbul-reports/lib/html/index.js:260:21)
at new LcovReport (/Users/myname/repos/server-project/node_modules/.pnpm/istanbul-reports@3.0.2/node_modules/istanbul-reports/lib/lcov/index.js:14:21)
at Object.create (/Users/myname/repos/server-project/node_modules/.pnpm/istanbul-reports@3.0.2/node_modules/istanbul-reports/index.js:22:16)
at /Users/myname/repos/server-project/node_modules/.pnpm/@jest+reporters@26.6.2/node_modules/@jest/reporters/build/CoverageReporter.js:248:20
at Array.forEach (<anonymous>)
at CoverageReporter.onRunComplete (/Users/myname/repos/server-project/node_modules/.pnpm/@jest+reporters@26.6.2/node_modules/@jest/reporters/build/CoverageReporter.js:240:25)
at ReporterDispatcher.onRunComplete (/Users/myname/repos/server-project/node_modules/.pnpm/@jest+core@26.6.3/node_modules/@jest/core/build/ReporterDispatcher.js:88:9)
at TestScheduler.scheduleTests (/Users/myname/repos/server-project/node_modules/.pnpm/@jest+core@26.6.3/node_modules/@jest/core/build/TestScheduler.js:350:5)
at runJest (/Users/myname/repos/server-project/node_modules/.pnpm/@jest+core@26.6.3/node_modules/@jest/core/build/runJest.js:376:19)
at _run10000 (/Users/myanme/repos/server-project/node_modules/.pnpm/@jest+core@26.6.3/node_modules/@jest/core/build/cli/index.js:416:7)
at runCLI (/Users/myname/repos/server-project/node_modules/.pnpm/@jest+core@26.6.3/node_modules/@jest/core/build/cli/index.js:271:3)
at Object.run (/Users/myname/repos/server-project/node_modules/.pnpm/jest-cli@26.6.3/node_modules/jest-cli/build/cli/index.js:163:37)

Test Suites: 2 passed, 2 total
Tests:       1 skipped, 4 passed, 5 total
Snapshots:   0 total
Time:        10.01 s
Ran all test suites.
 report is created on: /Users/myname/repos/server-project/test/html-report/report.html
ERROR: Coverage for lines (0%) does not meet global threshold (90%)
ERROR: Coverage for functions (0%) does not meet global threshold (90%)
ERROR: Coverage for branches (0%) does not meet global threshold (90%)
ERROR: Coverage for statements (0%) does not meet global threshold (90%)
-----------------------------------------|---------|----------|---------|---------|-------------------
File                                     | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------------------------------------|---------|----------|---------|---------|-------------------
All files                                |       0 |        0 |       0 |       0 |

api-gateway/src                         |       0 |        0 |       0 |       0 |

config.ts                              |       0 |      100 |     100 |       0 | 81

main.ts                                |       0 |        0 |       0 |       0 | 11-43

storage.ts                             |       0 |        0 |       0 |       0 | 6-19

libs/apollo-federation-tester/src       |       0 |        0 |       0 |       0 |

index.ts                               |       0 |        0 |       0 |       0 | 17-85

Please your help!
Thanks.


问:
Update mouse position after scroll
Found this cool effect on Codepen which I have forked and added sections below. When you move the cursor it warps the background image. The problem is that if you scroll down and then move the mouse, the effect does not move with the mouse and still warps the image where the cursor was before you scrolled. I need to somehow update the mouse position so that it is always where the cursor actually is. I'm not overly clued up on javacsript so have no idea how to achieve this, any help is appreciated!

var vertex = `
        attribute vec2 uv;
        attribute vec2 position;
        varying vec2 vUv;
        void main() {
                vUv = uv;
                gl_Position = vec4(position, 0, 1);
        }
`;
var fragment = `
        precision highp float;
        precision highp int;
        uniform sampler2D tWater;
        uniform sampler2D tFlow;
        uniform float uTime;
        varying vec2 vUv;
        uniform vec4 res;
        uniform vec2 img;

        vec2 centeredAspectRatio(vec2 uvs, vec2 factor){
                return uvs * factor - factor /2. + 0.5;
        }

        void main() {

            // R and G values are velocity in the x and y direction
            // B value is the velocity length
            vec3 flow = texture2D(tFlow, vUv).rgb;

            vec2 uv = .5 * gl_FragCoord.xy / res.xy ;

            // vec2 uv = .5 * gl_FragCoord.xy / res.xy ;
            vec2 myUV = (uv - vec2(0.5))*res.zw + vec2(0.5);
            myUV -= flow.xy * (0.15 * 1.2);

            vec2 myUV2 = (uv - vec2(0.5))*res.zw + vec2(0.5);
            myUV2 -= flow.xy * (0.125 * 1.2);

            vec2 myUV3 = (uv - vec2(0.5))*res.zw + vec2(0.5);
            myUV3 -= flow.xy * (0.10 * 1.4);

            vec3 tex = texture2D(tWater, myUV).rgb;
            vec3 tex2 = texture2D(tWater, myUV2).rgb;
            vec3 tex3 = texture2D(tWater, myUV3).rgb;

            gl_FragColor = vec4(tex.r, tex2.g, tex3.b, 1.0);
        }
`;
{
    var _size = [2048, 1638];
    var renderer = new ogl.Renderer({ dpr: 2 });
    var gl = renderer.gl;
    document.body.appendChild(gl.canvas);

    // Variable inputs to control flowmap
    var aspect = 1;
    var mouse = new ogl.Vec2(-1);
    var velocity = new ogl.Vec2();
    function resize() {
        gl.canvas.width = window.innerWidth * 2.0;
        gl.canvas.height = window.innerHeight * 2.0;
        gl.canvas.style.width = window.innerWidth + "px";
        gl.canvas.style.height = window.innerHeight + "px";

        var a1, a2;
        var imageAspect = _size[1] / _size[0];
        if (window.innerHeight / window.innerWidth < imageAspect) {
            a1 = 1;
            a2 = window.innerHeight / window.innerWidth / imageAspect;
        } else {
            a1 = window.innerWidth / window.innerHeight * imageAspect;
            a2 = 1;
        }
        mesh.program.uniforms.res.value = new ogl.Vec4(
            window.innerWidth,
            window.innerHeight,
            a1,
            a2
        );

        renderer.setSize(window.innerWidth, window.innerHeight);
        aspect = window.innerWidth / window.innerHeight;
    }
    var flowmap = new ogl.Flowmap(gl, {
        falloff: 0.3,
        dissipation: 0.92,
        alpha: 0.5
    });
    // Triangle that includes -1 to 1 range for 'position', and 0 to 1 range for 'uv'.
    var geometry = new ogl.Geometry(gl, {
        position: {
            size: 2,
            data: new Float32Array([-1, -1, 3, -1, -1, 3])
        },
        uv: { size: 2, data: new Float32Array([0, 0, 2, 0, 0, 2]) }
    });
    var texture = new ogl.Texture(gl, {
        minFilter: gl.LINEAR,
        magFilter: gl.LINEAR
    });
    var img = new Image();
    img.onload = () => (texture.image = img);
    img.crossOrigin = "Anonymous";
    img.src = "https://robindelaporte.fr/codepen/bg3.jpg";

    var a1, a2;
    var imageAspect = _size[1] / _size[0];
    if (window.innerHeight / window.innerWidth < imageAspect) {
        a1 = 1;
        a2 = window.innerHeight / window.innerWidth / imageAspect;
    } else {
        a1 = window.innerWidth / window.innerHeight * imageAspect;
        a2 = 1;
    }

    var program = new ogl.Program(gl, {
        vertex,
        fragment,
        uniforms: {
            uTime: { value: 0 },
            tWater: { value: texture },
            res: {
                value: new ogl.Vec4(window.innerWidth, window.innerHeight, a1, a2)
            },
            img: { value: new ogl.Vec2(_size[1], _size[0]) },
            // Note that the uniform is applied without using an object and value property
            // This is because the class alternates this texture between two render targets
            // and updates the value property after each render.
            tFlow: flowmap.uniform
        }
    });
    var mesh = new ogl.Mesh(gl, { geometry, program });

    window.addEventListener("resize", resize, false);
    resize();

    // Create handlers to get mouse position and velocity
    var isTouchCapable = "ontouchstart" in window;
    if (isTouchCapable) {
        window.addEventListener("touchstart", updateMouse, false);
        window.addEventListener("touchmove", updateMouse, { passive: false });
    } else {
        window.addEventListener("mousemove", updateMouse, false);
    }
    var lastTime;
    var lastMouse = new ogl.Vec2();
    function updateMouse(e) {
        e.preventDefault();

        if (e.changedTouches && e.changedTouches.length) {
            e.x = e.changedTouches[0].pageX;
            e.y = e.changedTouches[0].pageY;
        }
        if (e.x === undefined) {
            e.x = e.pageX;
            e.y = e.pageY;
        }
        // Get mouse value in 0 to 1 range, with y flipped
        mouse.set(e.x / gl.renderer.width, 1.0 - e.y / gl.renderer.height);
        // Calculate velocity
        if (!lastTime) {
            // First frame
            lastTime = performance.now();
            lastMouse.set(e.x, e.y);
        }

        var deltaX = e.x - lastMouse.x;
        var deltaY = e.y - lastMouse.y;

        lastMouse.set(e.x, e.y);

        var time = performance.now();

        // Avoid dividing by 0
        var delta = Math.max(10.4, time - lastTime);
        lastTime = time;
        velocity.x = deltaX / delta;
        velocity.y = deltaY / delta;
        // Flag update to prevent hanging velocity values when not moving
        velocity.needsUpdate = true;
    }
    requestAnimationFrame(update);
    function update(t) {
        requestAnimationFrame(update);
        // Reset velocity when mouse not moving
        if (!velocity.needsUpdate) {
            mouse.set(-1);
            velocity.set(0);
        }
        velocity.needsUpdate = false;
        // Update flowmap inputs
        flowmap.aspect = aspect;
        flowmap.mouse.copy(mouse);
        // Ease velocity input, slower when fading out
        flowmap.velocity.lerp(velocity, velocity.len ? 0.15 : 0.1);
        flowmap.update();
        program.uniforms.uTime.value = t * 0.01;
        renderer.render({ scene: mesh });
    }
}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>canvas {
    position: absolute;
    width: 100%;
    height: 100vh;
    left: 0;
    top:0;
}

.mask {
    position: absolute;
    z-index: 2;
    background: white;
    height: 100vh;
    width: 100vw;
    top:0;
    mix-blend-mode: screen;
    /* display: none; */
}

svg {
    width: 90%;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.sections{
    height:100vh;
}

.redtop{
    margin-top:100vh;
}

.red{
    background-color:red;
}

.blue{
    background-color:blue;
}</code>```

    <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1040 205.1" style="enable-background:new 0 0 1040 205.1;" xml:space="preserve">

        <g>
          <g>
            <path
              class="st0"
              d="M108.7,155.2l24.8,23.3c-2.1,3.1-4.9,6.2-8.3,9.2c-10.2,8.8-26.2,16.4-48.5,16.4C33.4,204.1,1,174.8,1,131.2
                c0-43.3,32.4-72.6,75.7-72.6c29.8,0,48.4,13.2,56.8,25.5l-28.7,26.7c-5.5-8-14.3-13.2-26.1-13.2c-18.3,0-32.4,12.6-32.4,33.6
                c0,3.7,0.4,7.2,1.3,10.4c1.5,5.9,4.4,10.8,8.2,14.5c5,4.9,11.6,8,19.1,8.7c1.2,0.1,2.5,0.2,3.8,0.2c10.5,0,18.7-4.6,24.2-11.1
                c0.7-0.8,1.3-1.6,1.8-2.4L108.7,155.2z"
            />
            <path
              class="st0"
              d="M239.9,59.4v42.5c-2.6-0.6-6.3-1.2-10.9-1.2c-11.5,0-26.7,4.9-32.4,12.6v88.3h-44.2V63.1h44.2V80
                C205.8,68.8,223.3,59.4,239.9,59.4z"
            />
            <path
              class="st0"
              d="M381.7,181.7c-9.3,9.7-21.1,16.9-34.5,20.4l0.7-0.1L381.7,181.7z"
            />
            <path
              class="st0"
              d="M539.8,92.8c-8.7-26-34.4-34.1-61.4-34.1c-21.2,0-45,6.3-62.8,21.5l7.2,12.6l8.6,15.2
                c11.2-9.5,25.5-14.6,39.3-14.6c17.8,0,28.1,8,28.1,20.1v16.6c-8.3-10.3-24.7-16.1-43-16.1c-7.1,0-14.8,1.2-21.9,4.1
                c-14,5.7-25.7,18-25.7,40.3c0,24.8,16.7,39,34.1,43.8c0.7,0.2,1.4,0.4,2.1,0.5c3.8,0.9,7.7,1.3,11.4,1.3c4.3,0,8.5-0.4,12.5-1.2
                c1.8-0.3,3.5-0.7,5.2-1.2c10.6-2.8,19.6-8.1,25.2-14.9v13.8h44.1V114C542.9,105.9,541.8,98.8,539.8,92.8z M498.8,165.1
                c-4.6,6.6-14.9,10-24.7,10c-11.8,0-22.1-5.2-22.1-16.1c0-10.9,10.3-16.1,22.1-16.1c9.8,0,20.1,3.4,24.7,9.8V165.1z"
            />
            <path
              class="st0"
              d="M605.3,201.1c-5.9-2.5-10.7-6.2-14.1-11.1C595.1,194.7,599.9,198.5,605.3,201.1z"
            />
            <path
              class="st0"
              d="M656.2,101.5h-28.1v19.6c-1.4-0.1-2.8-0.2-4.2-0.2c-18.2,0-33.7,11.5-39.6,27.5v-46.9h-22.9V63.1h22.9V25.2
                h43.9v37.9h28.1V101.5z"
            />
            <path
              class="st0"
              d="M660.2,195.9c-2.8,2.6-6.9,4.9-12.4,6.6c-5.1,1.5-11.3,2.5-18.7,2.6c12-1.5,22.4-7.9,29.1-17.2L660.2,195.9z"
            />
            <path
              class="st0"
              d="M725.5,26.2c0,14-11.2,25.5-25.2,25.5s-25.2-11.5-25.2-25.5S686.3,1,700.3,1S725.5,12.2,725.5,26.2z"
            />
            <polygon
              class="st0"
              points="891.5,63.1 879.4,93.8 873.7,108.5 837,201.6 790,201.6 760.2,125.9 747.6,93.8 735.6,63.1 782,63.1
                792.9,93.8 802.1,119.5 813.2,150.9 825.8,115.8 833.8,93.8 844.8,63.1        "
            />
            <path
              class="st0"
              d="M939.8,116.6c1.4-8,6.3-18.3,18-22.2c3-1,6.5-1.6,10.4-1.6c20.3,0,27.5,14.1,28.7,23.8H939.8z M968.2,204l2,0
                c21.2,0,44.1-6,57.9-18.4l-18.6-27.5c-7.7,7.5-24.6,11.8-34.4,11.8c-20.1,0-32.1-11.8-34.7-24.7h98.6v-9.5
                c0-47-29.8-77.2-70.8-77.2c-28.1,0-50.7,13.6-63.2,34.1c-2,3.3-3.8,6.8-5.2,10.5c-3.4,8.6-5.3,18-5.3,27.9
                c0,44.3,31.8,71.9,73.5,72.8L968.2,204z"
            />
          </g>
        </g>
        <polyline
          class="st0"
          points="678.2,201.4 678.2,63.1 722.3,63.1 722.3,201.4 "
        />
        <path
          class="st0"
          d="M395.3,135.8c0-10-1.3-19.2-3.8-27.5c-1.7-5.6-3.9-10.8-6.6-15.5c-12.1-21.6-33.9-34.1-60.4-34.1
        c-9.1,0-17.7,1.4-25.5,4.1c-25.9,11.5-43.9,37.5-43.9,67.8c0,37.8,28.1,69,64.5,73.5c3,0.4,6,0.5,9,0.5c6.4,0,12.7-0.8,18.6-2.4
        c13.3-3.5,25.2-10.7,34.5-20.4l-15.9-23.5c-7.7,7.5-24.7,11.8-34.4,11.8c-20.1,0-32.1-11.8-34.7-24.7h98.6V135.8z M296.1,116.6
        c1.7-10,9.2-23.8,28.4-23.8c6.4,0,11.5,1.4,15.5,3.6c8.7,4.8,12.4,13.5,13.1,20.2H296.1z"
        />
        <path
          class="st0"
          d="M658.1,187.8c-6.7,9.3-17.1,15.8-29.1,17.2h0c-1.7,0.2-3.4,0.3-5.2,0.3c-6.6,0-12.9-1.5-18.5-4.2
        c-5.5-2.7-10.3-6.5-14.1-11.1c0,0,0,0,0-0.1c-4.6-6.5-7-15.1-7-25.6v-15.9c6-16.1,21.4-27.5,39.6-27.5c1.4,0,2.8,0.1,4.2,0.2V152
        c0,7.1,3.6,12.6,9.8,13.8c0.8,0.1,1.6,0.2,2.5,0.2c4.9,0,9.7-1.7,11.2-3.4l1.9,7.4L658.1,187.8z"
        />
      </svg>

```

Title: Update mouse position after scroll

Body:
Found this cool effect on Codepen which I have forked and added sections below. When you move the cursor it warps the background image. The problem is that if you scroll down and then move the mouse, the effect does not move with the mouse and still warps the image where the cursor was before you scrolled. I need to somehow update the mouse position so that it is always where the cursor actually is. I'm not overly clued up on javacsript so have no idea how to achieve this, any help is appreciated!

var vertex = `
        attribute vec2 uv;
        attribute vec2 position;
        varying vec2 vUv;
        void main() {
                vUv = uv;
                gl_Position = vec4(position, 0, 1);
        }
`;
var fragment = `
        precision highp float;
        precision highp int;
        uniform sampler2D tWater;
        uniform sampler2D tFlow;
        uniform float uTime;
        varying vec2 vUv;
        uniform vec4 res;
        uniform vec2 img;

        vec2 centeredAspectRatio(vec2 uvs, vec2 factor){
                return uvs * factor - factor /2. + 0.5;
        }

        void main() {

            // R and G values are velocity in the x and y direction
            // B value is the velocity length
            vec3 flow = texture2D(tFlow, vUv).rgb;

            vec2 uv = .5 * gl_FragCoord.xy / res.xy ;

            // vec2 uv = .5 * gl_FragCoord.xy / res.xy ;
            vec2 myUV = (uv - vec2(0.5))*res.zw + vec2(0.5);
            myUV -= flow.xy * (0.15 * 1.2);

            vec2 myUV2 = (uv - vec2(0.5))*res.zw + vec2(0.5);
            myUV2 -= flow.xy * (0.125 * 1.2);

            vec2 myUV3 = (uv - vec2(0.5))*res.zw + vec2(0.5);
            myUV3 -= flow.xy * (0.10 * 1.4);

            vec3 tex = texture2D(tWater, myUV).rgb;
            vec3 tex2 = texture2D(tWater, myUV2).rgb;
            vec3 tex3 = texture2D(tWater, myUV3).rgb;

            gl_FragColor = vec4(tex.r, tex2.g, tex3.b, 1.0);
        }
`;
{
    var _size = [2048, 1638];
    var renderer = new ogl.Renderer({ dpr: 2 });
    var gl = renderer.gl;
    document.body.appendChild(gl.canvas);

    // Variable inputs to control flowmap
    var aspect = 1;
    var mouse = new ogl.Vec2(-1);
    var velocity = new ogl.Vec2();
    function resize() {
        gl.canvas.width = window.innerWidth * 2.0;
        gl.canvas.height = window.innerHeight * 2.0;
        gl.canvas.style.width = window.innerWidth + "px";
        gl.canvas.style.height = window.innerHeight + "px";

        var a1, a2;
        var imageAspect = _size[1] / _size[0];
        if (window.innerHeight / window.innerWidth < imageAspect) {
            a1 = 1;
            a2 = window.innerHeight / window.innerWidth / imageAspect;
        } else {
            a1 = window.innerWidth / window.innerHeight * imageAspect;
            a2 = 1;
        }
        mesh.program.uniforms.res.value = new ogl.Vec4(
            window.innerWidth,
            window.innerHeight,
            a1,
            a2
        );

        renderer.setSize(window.innerWidth, window.innerHeight);
        aspect = window.innerWidth / window.innerHeight;
    }
    var flowmap = new ogl.Flowmap(gl, {
        falloff: 0.3,
        dissipation: 0.92,
        alpha: 0.5
    });
    // Triangle that includes -1 to 1 range for 'position', and 0 to 1 range for 'uv'.
    var geometry = new ogl.Geometry(gl, {
        position: {
            size: 2,
            data: new Float32Array([-1, -1, 3, -1, -1, 3])
        },
        uv: { size: 2, data: new Float32Array([0, 0, 2, 0, 0, 2]) }
    });
    var texture = new ogl.Texture(gl, {
        minFilter: gl.LINEAR,
        magFilter: gl.LINEAR
    });
    var img = new Image();
    img.onload = () => (texture.image = img);
    img.crossOrigin = "Anonymous";
    img.src = "https://robindelaporte.fr/codepen/bg3.jpg";

    var a1, a2;
    var imageAspect = _size[1] / _size[0];
    if (window.innerHeight / window.innerWidth < imageAspect) {
        a1 = 1;
        a2 = window.innerHeight / window.innerWidth / imageAspect;
    } else {
        a1 = window.innerWidth / window.innerHeight * imageAspect;
        a2 = 1;
    }

    var program = new ogl.Program(gl, {
        vertex,
        fragment,
        uniforms: {
            uTime: { value: 0 },
            tWater: { value: texture },
            res: {
                value: new ogl.Vec4(window.innerWidth, window.innerHeight, a1, a2)
            },
            img: { value: new ogl.Vec2(_size[1], _size[0]) },
            // Note that the uniform is applied without using an object and value property
            // This is because the class alternates this texture between two render targets
            // and updates the value property after each render.
            tFlow: flowmap.uniform
        }
    });
    var mesh = new ogl.Mesh(gl, { geometry, program });

    window.addEventListener("resize", resize, false);
    resize();

    // Create handlers to get mouse position and velocity
    var isTouchCapable = "ontouchstart" in window;
    if (isTouchCapable) {
        window.addEventListener("touchstart", updateMouse, false);
        window.addEventListener("touchmove", updateMouse, { passive: false });
    } else {
        window.addEventListener("mousemove", updateMouse, false);
    }
    var lastTime;
    var lastMouse = new ogl.Vec2();
    function updateMouse(e) {
        e.preventDefault();

        if (e.changedTouches && e.changedTouches.length) {
            e.x = e.changedTouches[0].pageX;
            e.y = e.changedTouches[0].pageY;
        }
        if (e.x === undefined) {
            e.x = e.pageX;
            e.y = e.pageY;
        }
        // Get mouse value in 0 to 1 range, with y flipped
        mouse.set(e.x / gl.renderer.width, 1.0 - e.y / gl.renderer.height);
        // Calculate velocity
        if (!lastTime) {
            // First frame
            lastTime = performance.now();
            lastMouse.set(e.x, e.y);
        }

        var deltaX = e.x - lastMouse.x;
        var deltaY = e.y - lastMouse.y;

        lastMouse.set(e.x, e.y);

        var time = performance.now();

        // Avoid dividing by 0
        var delta = Math.max(10.4, time - lastTime);
        lastTime = time;
        velocity.x = deltaX / delta;
        velocity.y = deltaY / delta;
        // Flag update to prevent hanging velocity values when not moving
        velocity.needsUpdate = true;
    }
    requestAnimationFrame(update);
    function update(t) {
        requestAnimationFrame(update);
        // Reset velocity when mouse not moving
        if (!velocity.needsUpdate) {
            mouse.set(-1);
            velocity.set(0);
        }
        velocity.needsUpdate = false;
        // Update flowmap inputs
        flowmap.aspect = aspect;
        flowmap.mouse.copy(mouse);
        // Ease velocity input, slower when fading out
        flowmap.velocity.lerp(velocity, velocity.len ? 0.15 : 0.1);
        flowmap.update();
        program.uniforms.uTime.value = t * 0.01;
        renderer.render({ scene: mesh });
    }
}

canvas {
    position: absolute;
    width: 100%;
    height: 100vh;
    left: 0;
    top:0;
}

.mask {
    position: absolute;
    z-index: 2;
    background: white;
    height: 100vh;
    width: 100vw;
    top:0;
    mix-blend-mode: screen;
    /* display: none; */
}

svg {
    width: 90%;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.sections{
    height:100vh;
}

.redtop{
    margin-top:100vh;
}

.red{
    background-color:red;
}

.blue{
    background-color:blue;
}

    <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1040 205.1" style="enable-background:new 0 0 1040 205.1;" xml:space="preserve">

        <g>
          <g>
            <path
              class="st0"
              d="M108.7,155.2l24.8,23.3c-2.1,3.1-4.9,6.2-8.3,9.2c-10.2,8.8-26.2,16.4-48.5,16.4C33.4,204.1,1,174.8,1,131.2
                c0-43.3,32.4-72.6,75.7-72.6c29.8,0,48.4,13.2,56.8,25.5l-28.7,26.7c-5.5-8-14.3-13.2-26.1-13.2c-18.3,0-32.4,12.6-32.4,33.6
                c0,3.7,0.4,7.2,1.3,10.4c1.5,5.9,4.4,10.8,8.2,14.5c5,4.9,11.6,8,19.1,8.7c1.2,0.1,2.5,0.2,3.8,0.2c10.5,0,18.7-4.6,24.2-11.1
                c0.7-0.8,1.3-1.6,1.8-2.4L108.7,155.2z"
            />
            <path
              class="st0"
              d="M239.9,59.4v42.5c-2.6-0.6-6.3-1.2-10.9-1.2c-11.5,0-26.7,4.9-32.4,12.6v88.3h-44.2V63.1h44.2V80
                C205.8,68.8,223.3,59.4,239.9,59.4z"
            />
            <path
              class="st0"
              d="M381.7,181.7c-9.3,9.7-21.1,16.9-34.5,20.4l0.7-0.1L381.7,181.7z"
            />
            <path
              class="st0"
              d="M539.8,92.8c-8.7-26-34.4-34.1-61.4-34.1c-21.2,0-45,6.3-62.8,21.5l7.2,12.6l8.6,15.2
                c11.2-9.5,25.5-14.6,39.3-14.6c17.8,0,28.1,8,28.1,20.1v16.6c-8.3-10.3-24.7-16.1-43-16.1c-7.1,0-14.8,1.2-21.9,4.1
                c-14,5.7-25.7,18-25.7,40.3c0,24.8,16.7,39,34.1,43.8c0.7,0.2,1.4,0.4,2.1,0.5c3.8,0.9,7.7,1.3,11.4,1.3c4.3,0,8.5-0.4,12.5-1.2
                c1.8-0.3,3.5-0.7,5.2-1.2c10.6-2.8,19.6-8.1,25.2-14.9v13.8h44.1V114C542.9,105.9,541.8,98.8,539.8,92.8z M498.8,165.1
                c-4.6,6.6-14.9,10-24.7,10c-11.8,0-22.1-5.2-22.1-16.1c0-10.9,10.3-16.1,22.1-16.1c9.8,0,20.1,3.4,24.7,9.8V165.1z"
            />
            <path
              class="st0"
              d="M605.3,201.1c-5.9-2.5-10.7-6.2-14.1-11.1C595.1,194.7,599.9,198.5,605.3,201.1z"
            />
            <path
              class="st0"
              d="M656.2,101.5h-28.1v19.6c-1.4-0.1-2.8-0.2-4.2-0.2c-18.2,0-33.7,11.5-39.6,27.5v-46.9h-22.9V63.1h22.9V25.2
                h43.9v37.9h28.1V101.5z"
            />
            <path
              class="st0"
              d="M660.2,195.9c-2.8,2.6-6.9,4.9-12.4,6.6c-5.1,1.5-11.3,2.5-18.7,2.6c12-1.5,22.4-7.9,29.1-17.2L660.2,195.9z"
            />
            <path
              class="st0"
              d="M725.5,26.2c0,14-11.2,25.5-25.2,25.5s-25.2-11.5-25.2-25.5S686.3,1,700.3,1S725.5,12.2,725.5,26.2z"
            />
            <polygon
              class="st0"
              points="891.5,63.1 879.4,93.8 873.7,108.5 837,201.6 790,201.6 760.2,125.9 747.6,93.8 735.6,63.1 782,63.1
                792.9,93.8 802.1,119.5 813.2,150.9 825.8,115.8 833.8,93.8 844.8,63.1        "
            />
            <path
              class="st0"
              d="M939.8,116.6c1.4-8,6.3-18.3,18-22.2c3-1,6.5-1.6,10.4-1.6c20.3,0,27.5,14.1,28.7,23.8H939.8z M968.2,204l2,0
                c21.2,0,44.1-6,57.9-18.4l-18.6-27.5c-7.7,7.5-24.6,11.8-34.4,11.8c-20.1,0-32.1-11.8-34.7-24.7h98.6v-9.5
                c0-47-29.8-77.2-70.8-77.2c-28.1,0-50.7,13.6-63.2,34.1c-2,3.3-3.8,6.8-5.2,10.5c-3.4,8.6-5.3,18-5.3,27.9
                c0,44.3,31.8,71.9,73.5,72.8L968.2,204z"
            />
          </g>
        </g>
        <polyline
          class="st0"
          points="678.2,201.4 678.2,63.1 722.3,63.1 722.3,201.4 "
        />
        <path
          class="st0"
          d="M395.3,135.8c0-10-1.3-19.2-3.8-27.5c-1.7-5.6-3.9-10.8-6.6-15.5c-12.1-21.6-33.9-34.1-60.4-34.1
        c-9.1,0-17.7,1.4-25.5,4.1c-25.9,11.5-43.9,37.5-43.9,67.8c0,37.8,28.1,69,64.5,73.5c3,0.4,6,0.5,9,0.5c6.4,0,12.7-0.8,18.6-2.4
        c13.3-3.5,25.2-10.7,34.5-20.4l-15.9-23.5c-7.7,7.5-24.7,11.8-34.4,11.8c-20.1,0-32.1-11.8-34.7-24.7h98.6V135.8z M296.1,116.6
        c1.7-10,9.2-23.8,28.4-23.8c6.4,0,11.5,1.4,15.5,3.6c8.7,4.8,12.4,13.5,13.1,20.2H296.1z"
        />
        <path
          class="st0"
          d="M658.1,187.8c-6.7,9.3-17.1,15.8-29.1,17.2h0c-1.7,0.2-3.4,0.3-5.2,0.3c-6.6,0-12.9-1.5-18.5-4.2
        c-5.5-2.7-10.3-6.5-14.1-11.1c0,0,0,0,0-0.1c-4.6-6.5-7-15.1-7-25.6v-15.9c6-16.1,21.4-27.5,39.6-27.5c1.4,0,2.8,0.1,4.2,0.2V152
        c0,7.1,3.6,12.6,9.8,13.8c0.8,0.1,1.6,0.2,2.5,0.2c4.9,0,9.7-1.7,11.2-3.4l1.9,7.4L658.1,187.8z"
        />
      </svg>


问:
How to read a binary array (double or int) in PostgreSQL using libpq?
To speed the things up, I'm using a binary mode working directly with Libpq.
It's not a problem when a field is a single value.

But if the field is an array, I can't find any information on how to retrieve the data.
Are there any examples or explanation? Or is there no workaround for reverse engineering the source code?

Thanks

I looked up PostgreSQL documentation, but could not find any information on how to read arrays in a binary form.


问:
Cannot enter BytesIO with audio into AudioSegment.from_file correctly
I'm using PyTube to download an audio file from YouTube before converting it to an MP3. I want to do this using BytesIO.

My code is

```<code>yt = YouTube(youtube_link)
# Download file
audio = yt.streams.filter(only_audio=True).first()
audio_bytes = io.BytesIO()
print('Getting audio bytes')
audio.stream_to_buffer(audio_bytes)
print('Converting format')
sound = AudioSegment.from_file(file=audio_bytes).export(io.BytesIO(), 'mp3')
return dcc.send_bytes(sound.getvalue(), f'{yt.streams[0].title}.mp3')
</code>```

AudioSegment.from_file fails. The error is

```<code>    raise CouldntDecodeError(
pydub.exceptions.CouldntDecodeError: Decoding failed. ffmpeg returned error code: 1

Output from ffmpeg/avlib:

ffmpeg version 2022-07-04-git-dba7376d59-full_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 12.1.0 (Rev2, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
  libavutil      57. 27.100 / 57. 27.100
  libavcodec     59. 36.100 / 59. 36.100
  libavformat    59. 26.100 / 59. 26.100
  libavdevice    59.  6.100 / 59.  6.100
  libavfilter     8. 41.100 /  8. 41.100
  libswscale      6.  6.100 /  6.  6.100
  libswresample   4.  6.100 /  4.  6.100
  libpostproc    56.  5.100 / 56.  5.100
[cache @ 0000022fcb016200] Statistics, cache hits:0 cache misses:0
cache:pipe:0: Invalid data found when processing input
</code>```

Body:
I'm using PyTube to download an audio file from YouTube before converting it to an MP3. I want to do this using BytesIO.

My code is

yt = YouTube(youtube_link)
# Download file
audio = yt.streams.filter(only_audio=True).first()
audio_bytes = io.BytesIO()
print('Getting audio bytes')
audio.stream_to_buffer(audio_bytes)
print('Converting format')
sound = AudioSegment.from_file(file=audio_bytes).export(io.BytesIO(), 'mp3')
return dcc.send_bytes(sound.getvalue(), f'{yt.streams[0].title}.mp3')

AudioSegment.from_file fails. The error is

    raise CouldntDecodeError(
pydub.exceptions.CouldntDecodeError: Decoding failed. ffmpeg returned error code: 1

Output from ffmpeg/avlib:

ffmpeg version 2022-07-04-git-dba7376d59-full_build-www.gyan.dev Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 12.1.0 (Rev2, Built by MSYS2 project)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-bzlib --enable-lzma --enable-libsnappy --enable-zlib --enable-librist --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-libbluray --enable-libcaca --enable-sdl2 --enable-libdav1d --enable-libdavs2 --enable-libuavs3d --enable-libzvbi --enable-librav1e --enable-libsvtav1 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libaom --enable-libjxl --enable-libopenjpeg --enable-libvpx --enable-mediafoundation --enable-libass --enable-frei0r --enable-libfreetype --enable-libfribidi --enable-liblensfun --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libshaderc --enable-vulkan --enable-libplacebo --enable-opencl --enable-libcdio --enable-libgme --enable-libmodplug --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libshine --enable-libtheora --enable-libtwolame --enable-libvo-amrwbenc --enable-libilbc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-ladspa --enable-libbs2b --enable-libflite --enable-libmysofa --enable-librubberband --enable-libsoxr --enable-chromaprint
  libavutil      57. 27.100 / 57. 27.100
  libavcodec     59. 36.100 / 59. 36.100
  libavformat    59. 26.100 / 59. 26.100
  libavdevice    59.  6.100 / 59.  6.100
  libavfilter     8. 41.100 /  8. 41.100
  libswscale      6.  6.100 /  6.  6.100
  libswresample   4.  6.100 /  4.  6.100
  libpostproc    56.  5.100 / 56.  5.100
[cache @ 0000022fcb016200] Statistics, cache hits:0 cache misses:0
cache:pipe:0: Invalid data found when processing input


问:
Azure Retail Prices overview
Reading the official documentation about Azure Retail Prices overview, I found that we can make API calls filtering by serviceName

https://learn.microsoft.com/en-us/rest/api/cost-management/retail-prices/azure-retail-prices

https://prices.azure.com/api/retail/prices?$filter=serviceName eq
'Virtual Machines'

However, this assumes that we know the service's correct name.

How do we get a list of all service names in Azure?

In AWS there is an endpoint that returns a list of all AWS service names, and we can use that data in the subsequent API calls.

I found this article but it is not exactly what I would expect from Azure side.

https://dev.to/holger/how-to-retrieve-a-list-of-available-services-from-the-azure-retail-rates-prices-api-2nk6

Thank you!

Title: Azure Retail Prices overview


问:
Error When Trying To Fetch Webhooks List via Shopify API
I am building a Shopify App in PHP using Shopify's own PHP library for Shopify API

When I try to fetch current webhooks, I get this error:

Fatal error: Uncaught TypeError: Argument 1 passed to Shopify\Utils::loadCurrentSession() must be of the type array, null given, called in /www/doc/www.example.com/www/script/index.php on line 45 and defined in /www/doc/www.example.com/www/script/vendor/shopify/shopify-api/src/Utils.php:158 Stack trace: #0 /www/doc/www.example.com/www/script/index.php(45): Shopify\Utils::loadCurrentSession(NULL, NULL, NULL) #1 {main} thrown in /www/doc/www.example.com/www/script/vendor/shopify/shopify-api/src/Utils.php on line 158

PHP code:

```<code>$this->test_session = Utils::loadCurrentSession(
    $requestHeaders,
    $requestCookies,
    $isOnline
);
Webhookv2::webhooks(
    $this->test_session, // Session
    [], // Url Ids
    [], // Params
);
</code>```

Utils.php is part of the Shopify API PHP library

Body:
I am building a Shopify App in PHP using Shopify's own PHP library for Shopify API

When I try to fetch current webhooks, I get this error:

Fatal error: Uncaught TypeError: Argument 1 passed to Shopify\Utils::loadCurrentSession() must be of the type array, null given, called in /www/doc/www.example.com/www/script/index.php on line 45 and defined in /www/doc/www.example.com/www/script/vendor/shopify/shopify-api/src/Utils.php:158 Stack trace: #0 /www/doc/www.example.com/www/script/index.php(45): Shopify\Utils::loadCurrentSession(NULL, NULL, NULL) #1 {main} thrown in /www/doc/www.example.com/www/script/vendor/shopify/shopify-api/src/Utils.php on line 158

PHP code:

$this->test_session = Utils::loadCurrentSession(
    $requestHeaders,
    $requestCookies,
    $isOnline
);
Webhookv2::webhooks(
    $this->test_session, // Session
    [], // Url Ids
    [], // Params
);

Utils.php is part of the Shopify API PHP library


问:
How do I prevent the compiler from compiling obvious typos like if (somevalue = 0)?
I have once seen and used a helpful setting in Visual Studio that prevented the compiler from compiling obvious typos like

```<code>if (somevalue = 0)
</code>```

I do not find this setting anymore in VS2022.

What is the name of setting?

It was not the Code Analysis feature, but rather an option that really prevented this from being compiled.

Body:
I have once seen and used a helpful setting in Visual Studio that prevented the compiler from compiling obvious typos like

if (somevalue = 0)

I do not find this setting anymore in VS2022.

What is the name of setting?

It was not the Code Analysis feature, but rather an option that really prevented this from being compiled.


问:
Flask: Call a separate create_app function when running as cli vs server
I have a flask app using the app factory pattern and a create_app function.

In addition to providing server routes, I have also defined some CLI commands using @app.cli.command.

Is it possible to use a different create_app when running as a server vs when running a CLI command. Alternatively can any parameters be passed to create_app when running as a CLI command. I can achieve this by setting an environment variable each time I run the CLI command. E.g.

```<code>flask run
FLASK_MY_VARIABLE=x flask my_command
</code>```

I can then read this environment variable and act on it. Is it possible to do it in a way that I don't need to supply the environment variable and just run flask my_command while still either running a different create_app or having a parameter set so I know the app was invoked as a CLI command?

Body:
I have a flask app using the app factory pattern and a create_app function.

In addition to providing server routes, I have also defined some CLI commands using @app.cli.command.

Is it possible to use a different create_app when running as a server vs when running a CLI command. Alternatively can any parameters be passed to create_app when running as a CLI command. I can achieve this by setting an environment variable each time I run the CLI command. E.g.

flask run
FLASK_MY_VARIABLE=x flask my_command

I can then read this environment variable and act on it. Is it possible to do it in a way that I don't need to supply the environment variable and just run flask my_command while still either running a different create_app or having a parameter set so I know the app was invoked as a CLI command?


问:
'dartls -32007 file is not being analyzed' error whenever I open a file in Neovim
I am new to Neoviim. So, I am currently using Astronvim and I have setup flutter-tools plugin by following the guide here.

Whenever I open a dart file I get the following error: dartls -32007 file is not being analyzed

Autocompletion and Fluttter commands works, but some feature like color highlights and goto definitions stops working in a dart file sometimes.

My config look like this:

```<code>return {
  lsp = {
    skip_setup = { "dartls" }, -- skip lsp setup because flutter-tools will do it itself
    ["server-settings"] = {
      dartls = {
        -- any changes you want to make to the LSP setup, for example
        color = {
          enabled = true,
        },
        settings = {
          showTodos = true,
          completeFunctionCalls = true,
        },
      },
    },
  },
  plugins = {
    init = {
      {
        "akinsho/flutter-tools.nvim",
        requires = "nvim-lua/plenary.nvim",
        after = "mason-lspconfig.nvim", -- make sure to load after mason-lspconfig
        config = function()
          require("flutter-tools").setup {
            lsp = astronvim.lsp.server_settings "dartls", -- get the server settings and built in capabilities/on_attach
          }
        end,
      },
    },
  },
}
</code>```

Body:
I am new to Neoviim. So, I am currently using Astronvim and I have setup flutter-tools plugin by following the guide here.

Whenever I open a dart file I get the following error: dartls -32007 file is not being analyzed

Autocompletion and Fluttter commands works, but some feature like color highlights and goto definitions stops working in a dart file sometimes.

My config look like this:

return {
  lsp = {
    skip_setup = { "dartls" }, -- skip lsp setup because flutter-tools will do it itself
    ["server-settings"] = {
      dartls = {
        -- any changes you want to make to the LSP setup, for example
        color = {
          enabled = true,
        },
        settings = {
          showTodos = true,
          completeFunctionCalls = true,
        },
      },
    },
  },
  plugins = {
    init = {
      {
        "akinsho/flutter-tools.nvim",
        requires = "nvim-lua/plenary.nvim",
        after = "mason-lspconfig.nvim", -- make sure to load after mason-lspconfig
        config = function()
          require("flutter-tools").setup {
            lsp = astronvim.lsp.server_settings "dartls", -- get the server settings and built in capabilities/on_attach
          }
        end,
      },
    },
  },
}


问:
Update contact android - Kotlin
I need to update contact first and last name from emulator contact list.

my code:

```<code>        val contentResolver = APP_ACTIVITY?.contentResolver
    val contentValues = ContentValues().apply {
        put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,"$firstName")
        put(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,"$lastName")
    }

    Log.d("TAG", "editContactEmulator:$contentValues") //**prints: data2=Michael data3=Lou**

    val contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId.toString().toLong())
    Log.d("TAG", "editContactEmulator: $contactUri") // **prints:content://com.android.contacts/contacts/1**

  val res = contentResolver?.update(contactUri,contentValues, null, null)
    Log.d("TAG", "editContactEmulator : $res") **//RETURNS 0**
</code>```

so, the new values ( first and last name) are correct, the uri is the correct uri of the contact I want to update. BUT res is still 0 which means it did not update any rows.

Any Ideas?
( I added READ_CONTACTS and WRITE_CONTACTS permission - so that not the problem)

Title: Update contact android - Kotlin

Body:
I need to update contact first and last name from emulator contact list.

my code:

        val contentResolver = APP_ACTIVITY?.contentResolver
    val contentValues = ContentValues().apply {
        put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,"$firstName")
        put(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,"$lastName")
    }

    Log.d("TAG", "editContactEmulator:$contentValues") //**prints: data2=Michael data3=Lou**

    val contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId.toString().toLong())
    Log.d("TAG", "editContactEmulator: $contactUri") // **prints:content://com.android.contacts/contacts/1**

  val res = contentResolver?.update(contactUri,contentValues, null, null)
    Log.d("TAG", "editContactEmulator : $res") **//RETURNS 0**

so, the new values ( first and last name) are correct, the uri is the correct uri of the contact I want to update. BUT res is still 0 which means it did not update any rows.

Any Ideas?
( I added READ_CONTACTS and WRITE_CONTACTS permission - so that not the problem)


问:
Android: RelativeLayout measures child width incorrectly
What I want to do:

My idea is simple:

I have RecyclerView in RelativeLayout

When data loaded I set first item's text to TextView for pinned message

On scroll I take first visible item and set this item's text to header (TextView)

So I have:
RelativeLayout  + RecyclerView + TextView for pinned message + TextView for header
I update header on scroll, it looks like sticky header for list.

It is my layout:

```<code>    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/pin"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#ebebeb"
            android:gravity="center"
            android:padding="24dp"/>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/pin"/>

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/header"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignTop="@id/list"
            android:layout_alignEnd="@id/list"
            android:background="#33ff0000"
            android:gravity="center"
            android:padding="24dp"/>

    </RelativeLayout>
</code>```

And it is my Activity:

```<code>    class CustomAdapter() :
        RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

        var data: List<UUID> = listOf()

        class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
            val textView: TextView

            init {
                textView = view.findViewById(R.id.text)
            }
        }

        override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
            val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.list_item, viewGroup, false)

            return ViewHolder(view)
        }

        override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
            viewHolder.textView.text = data[position].toString()
        }

        override fun getItemCount() = data.size

    }

    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            val adapter = CustomAdapter()
            val header = findViewById<TextView>(R.id.header)
            findViewById<RecyclerView>(R.id.list).apply {
                this.adapter = adapter
                layoutManager = LinearLayoutManager(this@MainActivity, LinearLayoutManager.VERTICAL, false)
                addOnScrollListener(object : RecyclerView.OnScrollListener() {
                    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                        val position = recyclerView.topChildPosition() ?: return
                        if (position >= 0) {
                            header.text = adapter.data[position].toString().substring(0, 10)
                            Log.w("MainActivity", header.text.toString())
                        } else {
                            header.text = null
                        }
                    }
                })
            }

            /**
             * SIMULATE DATA LOADING
             */
            Handler(Looper.getMainLooper()).postDelayed({
                adapter.data = List(100) {
                    UUID.randomUUID()
                }
                findViewById<TextView>(R.id.pin).text = adapter.data[0].toString()
                adapter.notifyDataSetChanged()
            }, 1000L)
        }

        private fun RecyclerView.topChildPosition(): Int? {
            layoutManager.let { layoutManager ->
                if (layoutManager != null && layoutManager is LinearLayoutManager) {
                    return if (!layoutManager.reverseLayout) layoutManager.findFirstVisibleItemPosition()
                    else layoutManager.findLastVisibleItemPosition()
                } else {
                    val topChild: View = getChildAt(0) ?: return null
                    return getChildAdapterPosition(topChild)
                }
            }
        }

    }
</code>```

And what I have:

RelativeLayout measured views, header has text = null, so header's width = padding only

Data loaded (see "SIMULATE DATA LOADING" in the activity code), I call notifyDataSetChanged and I set text to header. Header (TextView) calls requestLayout() on set text, but RelativeLayout doesn't measured new width (actually, RelativeLayout calls header's onMeasure with widthMode == MeasureSpec.EXACTLY and pass old width)

When I scroll RecyclerView header remeasured successfully.
I can reproduce it on Android 26-33

What I can do with this.

I can change layout:
from this:

```<code><androidx.appcompat.widget.AppCompatTextView
    android:id="@+id/header"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@id/list"
    android:layout_alignEnd="@id/list"
    android:background="#33ff0000"
    android:gravity="center"
    android:padding="24dp"/>
</code>```

to this:

```<code>    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignTop="@id/list"
        android:layout_alignEnd="@id/list">

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/header"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:background="#33ff0000"
            android:gravity="center"
            android:padding="24dp"/>

    </FrameLayout>
</code>```

But actually I can't, because really my TextView in custom view extends from TextView and it is part of library. I don't know how it will be used in layouts.

I can call requestLayout() after data loading like this:

```<code>    adapter.notifyDataSetChanged()
    header.doOnNextLayout { header.post { header.requestLayout() } }
</code>```

But it is ugly.

So, finally my questions:

Do you know how to fix it without layout changing?

Do you know bug or some documented RelativeLayout behavior

Thanks for any help!

Body:
What I want to do:

My idea is simple:

I have RecyclerView in RelativeLayout

When data loaded I set first item's text to TextView for pinned message

On scroll I take first visible item and set this item's text to header (TextView)

So I have:
RelativeLayout  + RecyclerView + TextView for pinned message + TextView for header
I update header on scroll, it looks like sticky header for list.

It is my layout:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:id="@+id/pin"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#ebebeb"
            android:gravity="center"
            android:padding="24dp"/>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@+id/pin"/>

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/header"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignTop="@id/list"
            android:layout_alignEnd="@id/list"
            android:background="#33ff0000"
            android:gravity="center"
            android:padding="24dp"/>

    </RelativeLayout>

And it is my Activity:

    class CustomAdapter() :
        RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

        var data: List<UUID> = listOf()

        class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
            val textView: TextView

            init {
                textView = view.findViewById(R.id.text)
            }
        }

        override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
            val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.list_item, viewGroup, false)

            return ViewHolder(view)
        }

        override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
            viewHolder.textView.text = data[position].toString()
        }

        override fun getItemCount() = data.size

    }

    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            val adapter = CustomAdapter()
            val header = findViewById<TextView>(R.id.header)
            findViewById<RecyclerView>(R.id.list).apply {
                this.adapter = adapter
                layoutManager = LinearLayoutManager(this@MainActivity, LinearLayoutManager.VERTICAL, false)
                addOnScrollListener(object : RecyclerView.OnScrollListener() {
                    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                        val position = recyclerView.topChildPosition() ?: return
                        if (position >= 0) {
                            header.text = adapter.data[position].toString().substring(0, 10)
                            Log.w("MainActivity", header.text.toString())
                        } else {
                            header.text = null
                        }
                    }
                })
            }

            /**
             * SIMULATE DATA LOADING
             */
            Handler(Looper.getMainLooper()).postDelayed({
                adapter.data = List(100) {
                    UUID.randomUUID()
                }
                findViewById<TextView>(R.id.pin).text = adapter.data[0].toString()
                adapter.notifyDataSetChanged()
            }, 1000L)
        }

        private fun RecyclerView.topChildPosition(): Int? {
            layoutManager.let { layoutManager ->
                if (layoutManager != null && layoutManager is LinearLayoutManager) {
                    return if (!layoutManager.reverseLayout) layoutManager.findFirstVisibleItemPosition()
                    else layoutManager.findLastVisibleItemPosition()
                } else {
                    val topChild: View = getChildAt(0) ?: return null
                    return getChildAdapterPosition(topChild)
                }
            }
        }

    }

And what I have:

RelativeLayout measured views, header has text = null, so header's width = padding only

Data loaded (see "SIMULATE DATA LOADING" in the activity code), I call notifyDataSetChanged and I set text to header. Header (TextView) calls requestLayout() on set text, but RelativeLayout doesn't measured new width (actually, RelativeLayout calls header's onMeasure with widthMode == MeasureSpec.EXACTLY and pass old width)

When I scroll RecyclerView header remeasured successfully.
I can reproduce it on Android 26-33

What I can do with this.

I can change layout:
from this:

<androidx.appcompat.widget.AppCompatTextView
    android:id="@+id/header"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignTop="@id/list"
    android:layout_alignEnd="@id/list"
    android:background="#33ff0000"
    android:gravity="center"
    android:padding="24dp"/>

to this:

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignTop="@id/list"
        android:layout_alignEnd="@id/list">

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/header"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end"
            android:background="#33ff0000"
            android:gravity="center"
            android:padding="24dp"/>

    </FrameLayout>

But actually I can't, because really my TextView in custom view extends from TextView and it is part of library. I don't know how it will be used in layouts.

I can call requestLayout() after data loading like this:

    adapter.notifyDataSetChanged()
    header.doOnNextLayout { header.post { header.requestLayout() } }

But it is ugly.

So, finally my questions:

Do you know how to fix it without layout changing?

Do you know bug or some documented RelativeLayout behavior

Thanks for any help!


问:
cannot target 443(8443) on ALB
I'm trying to deploy my spring boot in https using ec2, Route 53.

When I try to set ALB's target groups to register for port 443, it failed in health check.
I opened 443 in security group which apply to ALB, also VPC's network ACL.

So I googled it and found out that "even though 443 is opened, if no one's listening to port 443, then connection to 443 will fail". Reading this comment, I decided to run springboot on port 443.

So I've changed application.properties to use 443 and also shell script file in charge of deploying to use 443. But it didn't work, server couldn't run on 443.

There was no other process on 443,  my firewall setting is opened to 443 too.
After some googling, Someone told me "one some *nix system, 1 to 1024 ports can only be used by root previlege..." So, I changed settings and run my springboot on 8443 , finally succeeded.

But when I try to register target to 8443 it also returns unhealthy, even though I opened 8443 on security group, and there is one process listening to 8443.
I'm kind of lost here.
Is my approach is wrong? what can I do to make it healthy?

I bought domain on other site.
Got SSL Certification from ACM.
Added this SSL as CNAME into Route53 record.
Feeling embarrassed because i'm beginner in aws, also not completly understanding what i am doing.
Right now I'm just thinking making target healthy would solve the problem..
Any references that will help me getting out of this problem would be really helpful. thanks.

Title: cannot target 443(8443) on ALB


问:
I want a clean URL but i cannot GET string on the other page. I am using preg_replace to remove spaces with -
i want to send id and post caption through my page to the post page. When i try to GET id only, it works but when i try to get caption it does not work. can someone please help? It's been many days but cannnot get rid of this error.
Thank you

.htaccess-rule

```<code>RewriteRule ^post/([0-9]+)/([0-9a-zA-Z]+)$ post.php?id=$1&cap=$2 [QSA,L]
</code>```

Sending it from list page

```<code>$cp = preg_replace('/[^A-Za-z0-9\-]+/', '-', $row['caption']);
$cpnew = str_replace(" ", "-", $cp);
<?php echo "<a href='post/$id/$cpnew'>"; ?>
</code>```

Getting on post page

```<code>$cap ="". preg_replace('^[\x{0590}-\x{05fe} ]+', '', $_GET['cap']);
$capnew = str_replace("-", " ", $cap);
</code>```

Body:
i want to send id and post caption through my page to the post page. When i try to GET id only, it works but when i try to get caption it does not work. can someone please help? It's been many days but cannnot get rid of this error.
Thank you

.htaccess-rule

RewriteRule ^post/([0-9]+)/([0-9a-zA-Z]+)$ post.php?id=$1&cap=$2 [QSA,L]

Sending it from list page

$cp = preg_replace('/[^A-Za-z0-9\-]+/', '-', $row['caption']);
$cpnew = str_replace(" ", "-", $cp);
<?php echo ""; ?>

Getting on post page

$cap ="". preg_replace('^[\x{0590}-\x{05fe} ]+', '', $_GET['cap']);
$capnew = str_replace("-", " ", $cap);


问:
How to upload large pytorch model to azure?
I have locally pretrained pytorch (.pth) model that has ~500mb in size. I have created azure function which loads the model from azure static storage, but it takes over 5 minutes to load, which causes HTTP request to function to time out. How could I approach storing/loading model of this size?</p>


问:
Where can I see a history of the commands i have ran in Terminal in Android Studio?
Android Studio has a tool window Terminal where you can write commands and have them executed.

Is there anywhere that the history of these commands (and there output) are saved so I can see the script that was executed? I thought the script would be saved on the local machine but I can't seem to find it.


问:
Notes not appearingE/SQLiteLog( 5621): (1) table note has no column named is_synced_with_cloud in"INSERT INTO note(user_id,text,is_synced_with_cloud)
I am getting this error:
E/SQLiteLog( 5621): (1) table note has no column named is_synced_with_cloud in "INSERT INTO note (user_id, text, is_synced_with_cloud) VALUES (?, ?, ?)"

This is my code:

```<code>import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:myprogram/services/crud/crud_exceptions.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' show join;

class NotesService {
  Database? _db;
  List<DatabaseNote> _notes = [];

  static final NotesService _shared = NotesService._sharedInstance();

  NotesService._sharedInstance() {
    _notesStreamController = StreamController<List<DatabaseNote>>.broadcast(
      onListen: () {
        _notesStreamController.sink.add(_notes);
      },
    );
  }
  factory NotesService() => _shared;

  late final StreamController<List<DatabaseNote>> _notesStreamController;

  Stream<List<DatabaseNote>> get allNotes => _notesStreamController.stream;

  Future<DatabaseUser> getOrCreateUser({required String email}) async {
    try {
      final user = await getUser(email: email);
      return user;
    } on CouldNotFindUser {
      final createdUser = await createUser(email: email);
      return createdUser;
    } catch (e) {
      rethrow;
    }
  }
  Future<void> _cacheNotes() async {
    final allNotes = await getAllNotes();
    _notes = allNotes.toList();
    _notesStreamController.add(_notes);
  }
  Future<DatabaseNote> updateNote({
    required DatabaseNote note,
    required String text,
  }) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    // make sure note exists
    await getNote(id: note.id);
    // update DB
    final updatesCount = await db.update(noteTable, {
      textColumn: text,
      isSyncedWithCloudColumn: 0,
    });
    if (updatesCount == 0) {
      throw CouldNotUpdateNote();
    } else {
      final updatedNote = await getNote(id: note.id);
      _notes.removeWhere((note) => note.id == updatedNote.id);
      _notes.add(updatedNote);
      _notesStreamController.add(_notes);
      return updatedNote;
    }
  }
  Future<Iterable<DatabaseNote>> getAllNotes() async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final notes = await db.query(noteTable);
    return notes.map((noteRow) => DatabaseNote.fromRow(noteRow));
  }
  Future<DatabaseNote> getNote({required int id}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final notes = await db.query(
      noteTable,
      limit: 1,
      where: 'id = ?',
      whereArgs: [id],
    );
    if (notes.isEmpty) {
      throw CouldNotFindNote();
    } else {
      final note = DatabaseNote.fromRow(notes.first);
      _notes.removeWhere((note) => note.id == id);
      _notes.add(note);
      _notesStreamController.add(_notes);
      return note;
    }
  }
  Future<int> deleteAllNotes() async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final numberOfDeletions = await db.delete(noteTable);
    _notes = [];
    _notesStreamController.add(_notes);
    return numberOfDeletions;
  }
  Future<void> deleteNote({required int id}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final deletedCount = await db.delete(
      noteTable,
      where: 'id = ?',
      whereArgs: [id],
    );
    if (deletedCount == 0) {
      throw CouldNotDeleteNote();
    } else {
      _notes.removeWhere((note) => note.id == id);
      _notesStreamController.add(_notes);
    }
  }
  Future<DatabaseNote> createNote({required DatabaseUser owner}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    // make sure owner exists in the database with the correct id
    final dbUser = await getUser(email: owner.email);
    if (dbUser != owner) {
      throw CouldNotFindUser();
    }
    const text = '';
    // create the note
    final noteId = await db.insert(noteTable, {
      userIdColumn: owner.id,
      textColumn: text,
      isSyncedWithCloudColumn: 1,
    });
    final note = DatabaseNote(
      id: noteId,
      userId: owner.id,
      text: text,
      isSyncedWithCloud: true,
    );
    _notes.add(note);
    _notesStreamController.add(_notes);
    return note;
  }
  Future<DatabaseUser> getUser({required String email}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final results = await db.query(
      userTable,
      limit: 1,
      where: 'email = ?',
      whereArgs: [email.toLowerCase()],
    );
    if (results.isEmpty) {
      throw CouldNotFindUser();
    } else {
      return DatabaseUser.fromRow(results.first);
    }
  }
  Future<DatabaseUser> createUser({required String email}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final results = await db.query(
      userTable,
      limit: 1,
      where: 'email = ?',
      whereArgs: [email.toLowerCase()],
    );
    if (results.isNotEmpty) {
      throw UserAlreadyExists();
    }
    final userId = await db.insert(userTable, {
      emailColumn: email.toLowerCase(),
    });
    return DatabaseUser(
      id: userId,
      email: email,
    );
  }
  Future<void> deleteUser({required String email}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final deletedCount = await db.delete(
      userTable,
      where: 'email = ?',
      whereArgs: [email.toLowerCase()],
    );
    if (deletedCount != 1) {
      throw CouldNotDeleteUser();
    }
  }
  Database _getDatabaseOrThrow() {
    final db = _db;
    if (db == null) {
      throw DatabaseIsNotOpen();
    } else {
      return db;
    }
  }
  Future<void> close() async {
    final db = _db;
    if (db == null) {
      throw DatabaseIsNotOpen();
    } else {
      await db.close();
      _db = null;
    }
  }
  Future<void> _ensureDbIsOpen() async {
    try {
      await open();
    } on DatabaseAlreadyOpenException {
      // empty
    }
  }
  Future<void> open() async {
    if (_db != null) {
      throw DatabaseAlreadyOpenException();
    }
    try {
      final docsPath = await getApplicationDocumentsDirectory();
      final dbPath = join(docsPath.path, dbName);
      final db = await openDatabase(dbPath);
      _db = db;
      // create the user table
      await db.execute(createUserTable);
      // create note table
      await db.execute(createNoteTable);
      await _cacheNotes();
    } on MissingPlatformDirectoryException {
      throw UnableToGetDocumentsDirectory();
    }
  }
}
@immutable
class DatabaseUser {
  final int id;
  final String email;
  const DatabaseUser({
    required this.id,
    required this.email,
  });
  DatabaseUser.fromRow(Map<String, Object?> map)
      : id = map[idColumn] as int,
        email = map[emailColumn] as String;
  @override
  String toString() => 'Person, ID = $id, email = $email';
  @override
  bool operator ==(covariant DatabaseUser other) => id == other.id;
  @override
  int get hashCode => id.hashCode;
}
class DatabaseNote {
  final int id;
  final int userId;
  final String text;
  final bool isSyncedWithCloud;
  DatabaseNote({
    required this.id,
    required this.userId,
    required this.text,
    required this.isSyncedWithCloud,
  });
  DatabaseNote.fromRow(Map<String, Object?> map)
      : id = map[idColumn] as int,
        userId = map[userIdColumn] as int,
        text = map[textColumn] as String,
        isSyncedWithCloud =
        (map[isSyncedWithCloudColumn] as int) == 1 ? true : false;
  @override
  String toString() =>
      'Note, ID = $id, userId = $userId, isSyncedWithCloud = $isSyncedWithCloud, text = $text';
  @override
  bool operator ==(covariant DatabaseNote other) => id == other.id;
  @override
  int get hashCode => id.hashCode;
}
const dbName = 'notes.db';
const noteTable = 'note';
const userTable = 'user';
const idColumn = 'id';
const emailColumn = 'email';
const userIdColumn = 'user_id';
const textColumn = 'text';
const isSyncedWithCloudColumn = 'is_synced_with_cloud';
const createUserTable = '''CREATE TABLE IF NOT EXISTS "user" (
        "id"    INTEGER NOT NULL,
        "email" TEXT NOT NULL UNIQUE,
        PRIMARY KEY("id" AUTOINCREMENT)
      );''';
const createNoteTable = '''CREATE TABLE IF NOT EXISTS "note" (
        "id"    INTEGER NOT NULL,
        "user_id"   INTEGER NOT NULL,
        "text"  TEXT,
        "is_synced_with_cloud"  INTEGER NOT NULL DEFAULT 0,
        FOREIGN KEY("user_id") REFERENCES "user"("id"),
        PRIMARY KEY("id" AUTOINCREMENT)
      );''';
</code>```

This is a notes app. When you press the plus button it takes you to the new notes view and when any text is typed  into the text text space and you go back to the notes view its supposed to automatically save and appear on the notes view but noting appears

Body:
I am getting this error:
E/SQLiteLog( 5621): (1) table note has no column named is_synced_with_cloud in "INSERT INTO note (user_id, text, is_synced_with_cloud) VALUES (?, ?, ?)"

This is my code:

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:myprogram/services/crud/crud_exceptions.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' show join;

class NotesService {
  Database? _db;
  List<DatabaseNote> _notes = [];

  static final NotesService _shared = NotesService._sharedInstance();

  NotesService._sharedInstance() {
    _notesStreamController = StreamController<List<DatabaseNote>>.broadcast(
      onListen: () {
        _notesStreamController.sink.add(_notes);
      },
    );
  }
  factory NotesService() => _shared;

  late final StreamController<List<DatabaseNote>> _notesStreamController;

  Stream<List<DatabaseNote>> get allNotes => _notesStreamController.stream;

  Future<DatabaseUser> getOrCreateUser({required String email}) async {
    try {
      final user = await getUser(email: email);
      return user;
    } on CouldNotFindUser {
      final createdUser = await createUser(email: email);
      return createdUser;
    } catch (e) {
      rethrow;
    }
  }
  Future<void> _cacheNotes() async {
    final allNotes = await getAllNotes();
    _notes = allNotes.toList();
    _notesStreamController.add(_notes);
  }
  Future<DatabaseNote> updateNote({
    required DatabaseNote note,
    required String text,
  }) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    // make sure note exists
    await getNote(id: note.id);
    // update DB
    final updatesCount = await db.update(noteTable, {
      textColumn: text,
      isSyncedWithCloudColumn: 0,
    });
    if (updatesCount == 0) {
      throw CouldNotUpdateNote();
    } else {
      final updatedNote = await getNote(id: note.id);
      _notes.removeWhere((note) => note.id == updatedNote.id);
      _notes.add(updatedNote);
      _notesStreamController.add(_notes);
      return updatedNote;
    }
  }
  Future<Iterable<DatabaseNote>> getAllNotes() async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final notes = await db.query(noteTable);
    return notes.map((noteRow) => DatabaseNote.fromRow(noteRow));
  }
  Future<DatabaseNote> getNote({required int id}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final notes = await db.query(
      noteTable,
      limit: 1,
      where: 'id = ?',
      whereArgs: [id],
    );
    if (notes.isEmpty) {
      throw CouldNotFindNote();
    } else {
      final note = DatabaseNote.fromRow(notes.first);
      _notes.removeWhere((note) => note.id == id);
      _notes.add(note);
      _notesStreamController.add(_notes);
      return note;
    }
  }
  Future<int> deleteAllNotes() async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final numberOfDeletions = await db.delete(noteTable);
    _notes = [];
    _notesStreamController.add(_notes);
    return numberOfDeletions;
  }
  Future<void> deleteNote({required int id}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final deletedCount = await db.delete(
      noteTable,
      where: 'id = ?',
      whereArgs: [id],
    );
    if (deletedCount == 0) {
      throw CouldNotDeleteNote();
    } else {
      _notes.removeWhere((note) => note.id == id);
      _notesStreamController.add(_notes);
    }
  }
  Future<DatabaseNote> createNote({required DatabaseUser owner}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    // make sure owner exists in the database with the correct id
    final dbUser = await getUser(email: owner.email);
    if (dbUser != owner) {
      throw CouldNotFindUser();
    }
    const text = '';
    // create the note
    final noteId = await db.insert(noteTable, {
      userIdColumn: owner.id,
      textColumn: text,
      isSyncedWithCloudColumn: 1,
    });
    final note = DatabaseNote(
      id: noteId,
      userId: owner.id,
      text: text,
      isSyncedWithCloud: true,
    );
    _notes.add(note);
    _notesStreamController.add(_notes);
    return note;
  }
  Future<DatabaseUser> getUser({required String email}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final results = await db.query(
      userTable,
      limit: 1,
      where: 'email = ?',
      whereArgs: [email.toLowerCase()],
    );
    if (results.isEmpty) {
      throw CouldNotFindUser();
    } else {
      return DatabaseUser.fromRow(results.first);
    }
  }
  Future<DatabaseUser> createUser({required String email}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final results = await db.query(
      userTable,
      limit: 1,
      where: 'email = ?',
      whereArgs: [email.toLowerCase()],
    );
    if (results.isNotEmpty) {
      throw UserAlreadyExists();
    }
    final userId = await db.insert(userTable, {
      emailColumn: email.toLowerCase(),
    });
    return DatabaseUser(
      id: userId,
      email: email,
    );
  }
  Future<void> deleteUser({required String email}) async {
    await _ensureDbIsOpen();
    final db = _getDatabaseOrThrow();
    final deletedCount = await db.delete(
      userTable,
      where: 'email = ?',
      whereArgs: [email.toLowerCase()],
    );
    if (deletedCount != 1) {
      throw CouldNotDeleteUser();
    }
  }
  Database _getDatabaseOrThrow() {
    final db = _db;
    if (db == null) {
      throw DatabaseIsNotOpen();
    } else {
      return db;
    }
  }
  Future<void> close() async {
    final db = _db;
    if (db == null) {
      throw DatabaseIsNotOpen();
    } else {
      await db.close();
      _db = null;
    }
  }
  Future<void> _ensureDbIsOpen() async {
    try {
      await open();
    } on DatabaseAlreadyOpenException {
      // empty
    }
  }
  Future<void> open() async {
    if (_db != null) {
      throw DatabaseAlreadyOpenException();
    }
    try {
      final docsPath = await getApplicationDocumentsDirectory();
      final dbPath = join(docsPath.path, dbName);
      final db = await openDatabase(dbPath);
      _db = db;
      // create the user table
      await db.execute(createUserTable);
      // create note table
      await db.execute(createNoteTable);
      await _cacheNotes();
    } on MissingPlatformDirectoryException {
      throw UnableToGetDocumentsDirectory();
    }
  }
}
@immutable
class DatabaseUser {
  final int id;
  final String email;
  const DatabaseUser({
    required this.id,
    required this.email,
  });
  DatabaseUser.fromRow(Map<String, Object?> map)
      : id = map[idColumn] as int,
        email = map[emailColumn] as String;
  @override
  String toString() => 'Person, ID = $id, email = $email';
  @override
  bool operator ==(covariant DatabaseUser other) => id == other.id;
  @override
  int get hashCode => id.hashCode;
}
class DatabaseNote {
  final int id;
  final int userId;
  final String text;
  final bool isSyncedWithCloud;
  DatabaseNote({
    required this.id,
    required this.userId,
    required this.text,
    required this.isSyncedWithCloud,
  });
  DatabaseNote.fromRow(Map<String, Object?> map)
      : id = map[idColumn] as int,
        userId = map[userIdColumn] as int,
        text = map[textColumn] as String,
        isSyncedWithCloud =
        (map[isSyncedWithCloudColumn] as int) == 1 ? true : false;
  @override
  String toString() =>
      'Note, ID = $id, userId = $userId, isSyncedWithCloud = $isSyncedWithCloud, text = $text';
  @override
  bool operator ==(covariant DatabaseNote other) => id == other.id;
  @override
  int get hashCode => id.hashCode;
}
const dbName = 'notes.db';
const noteTable = 'note';
const userTable = 'user';
const idColumn = 'id';
const emailColumn = 'email';
const userIdColumn = 'user_id';
const textColumn = 'text';
const isSyncedWithCloudColumn = 'is_synced_with_cloud';
const createUserTable = '''CREATE TABLE IF NOT EXISTS "user" (
        "id"    INTEGER NOT NULL,
        "email" TEXT NOT NULL UNIQUE,
        PRIMARY KEY("id" AUTOINCREMENT)
      );''';
const createNoteTable = '''CREATE TABLE IF NOT EXISTS "note" (
        "id"    INTEGER NOT NULL,
        "user_id"   INTEGER NOT NULL,
        "text"  TEXT,
        "is_synced_with_cloud"  INTEGER NOT NULL DEFAULT 0,
        FOREIGN KEY("user_id") REFERENCES "user"("id"),
        PRIMARY KEY("id" AUTOINCREMENT)
      );''';

This is a notes app. When you press the plus button it takes you to the new notes view and when any text is typed  into the text text space and you go back to the notes view its supposed to automatically save and appear on the notes view but noting appears