问:
Animating a multi-keyframe step animation using setTimeout using JS
I'm hoping to achieve the implementation of a CSS animation using only a timeout function. I'm building a plugin where the platform isn't browser based, so don't have access to requestAnimationFrame so need to use setTimeout.

Below I've achieved the animation where it has only two steps (0%, 100%) using the timeout function. I'm wondering how this would be possible if it had multiple steps; e.g. if fadeInStaggered had 0%, 30%, 100% keyframes of opacity: 0, opacity: 0.5, opacity: 1.

I'm thinking I might need to loop through an array like [{ progress: 0, opacity: 0}, { progress: 30, opacity: 0.5}, { progress: 100, opacity: 1}] and run multiple time intervals after which does step 1 → step 2, then step 2 → step 3?

Thanks in advance!

let element = document.querySelector("#fadeIn");

let opacity = 0;
let fadeAmount = 0.1;

const playAnimation = setInterval(() => {
      if (!element.style.opacity) {
      element.style.opacity =0;
      }
      element.style.opacity = opacity;
      opacity += fadeAmount;
      if (opacity >= 1) {
        clearInterval(playAnimation);
      }
  },  100);```
<pre class="snippet-code-css lang-css prettyprint-override"><code>.fadeIn {
  animation: fadeInAnimation ease 2s both;
}

@keyframes fadeInAnimation {
  0% {
    opacity: 0;
  }
  100 % {
    opacity: 1;
  }
}</code>```

Fade me in with Timeout

Fade me in with CSS

```

Body:
I'm hoping to achieve the implementation of a CSS animation using only a timeout function. I'm building a plugin where the platform isn't browser based, so don't have access to requestAnimationFrame so need to use setTimeout.

Below I've achieved the animation where it has only two steps (0%, 100%) using the timeout function. I'm wondering how this would be possible if it had multiple steps; e.g. if fadeInStaggered had 0%, 30%, 100% keyframes of opacity: 0, opacity: 0.5, opacity: 1.

I'm thinking I might need to loop through an array like [{ progress: 0, opacity: 0}, { progress: 30, opacity: 0.5}, { progress: 100, opacity: 1}] and run multiple time intervals after which does step 1 → step 2, then step 2 → step 3?

Thanks in advance!

let element = document.querySelector("#fadeIn");

let opacity = 0;
let fadeAmount = 0.1;

const playAnimation = setInterval(() => {
      if (!element.style.opacity) {
      element.style.opacity =0;
      }
      element.style.opacity = opacity;
      opacity += fadeAmount;
      if (opacity >= 1) {
        clearInterval(playAnimation);
      }
  },  100);

.fadeIn {
  animation: fadeInAnimation ease 2s both;
}

@keyframes fadeInAnimation {
  0% {
    opacity: 0;
  }
  100 % {
    opacity: 1;
  }
}

Fade me in with Timeout

Fade me in with CSS


来源: stackexchange

问:
Snowflakes SQL convert timestamp_ltz to Pacific Time zone
I have a query that returns a date with type timestamp_ltz, but i want to convert it to the pacific time zone

```<code>select
      INVOICE."ID" "ID",
      INVOICE.CUSTOMER_ID CUSTOMER_ID,
      INVOICE."DATE":: timestamp_ltz,
</code>```

How can i make this conversion in snowflakes?

I tried to select using

```<code>convert_timezone('UTC','America/Los_Angeles', INVOICE."DATE")::timestamp_ltz
</code>```

but it's returning an error

ContentLicense: CC BY-SA 4.0

Body:
I have a query that returns a date with type timestamp_ltz, but i want to convert it to the pacific time zone

select
      INVOICE."ID" "ID",
      INVOICE.CUSTOMER_ID CUSTOMER_ID,
      INVOICE."DATE":: timestamp_ltz,

How can i make this conversion in snowflakes?

I tried to select using

convert_timezone('UTC','America/Los_Angeles', INVOICE."DATE")::timestamp_ltz

but it's returning an error


问:
Python plot sub plots with x as Index
I am trying to do a plot that uses sub plots in Python, but it doesn't seem to be working.
SO I have a dataframe and there is an Index. This index holds datetime. I have two columns that I would like to plot, and I am trying to use sub plots. Data1 and Data2 are my column names. My code is below

```<code>fig, ax1 = plt.subplots()

ax2 = ax1.twinx()
ax1.plot(x=df[index], y=df['Data1'])
ax2.plot(x=df[index], y=df['Data2'])

plt.show()
</code>```

When I run this I get the following error.

TypeError: 'DataFrame' object cannot be interpreted as an integer

Title: Python plot sub plots with x as Index

Body:
I am trying to do a plot that uses sub plots in Python, but it doesn't seem to be working.
SO I have a dataframe and there is an Index. This index holds datetime. I have two columns that I would like to plot, and I am trying to use sub plots. Data1 and Data2 are my column names. My code is below

fig, ax1 = plt.subplots()

ax2 = ax1.twinx()
ax1.plot(x=df[index], y=df['Data1'])
ax2.plot(x=df[index], y=df['Data2'])

plt.show()

When I run this I get the following error.

TypeError: 'DataFrame' object cannot be interpreted as an integer


问:
Error when sending an audio file from my app to WhatsApp
For some time I've been trying to implement the functionality of sending an audio file from my app through WhatsApp. When debugging everything seems to work correctly in the application, the audio file is generated and saved correctly in the external storage of the device, the WhatsApp window opens and allows me to select the chat to which I want to send the audio. The problem is that when I press the send button, WhatsApp returns the message "Failed to share. Please try again" (I leave a screenshot of the error so that it can be better viewed, in addition to the code used to add said functionality).

Capture of the error shown on the screen by WhatsApp when trying to share the audio:

https://i.stack.imgur.com/gZuLt.jpg

Code used:

```<code>//////Boton//////

btn1.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View view) {

        try {
            String mediaPath = copyFiletoExternalStorage(R.raw.audio1, "audio1.mp3");
            File myFile = new File(mediaPath);
            Uri newUri = getUriForFile(wspActivity.this, "com.restart.shareaudiofiles.fileprovider", myFile);
            Intent compartirAudio = new Intent(android.content.Intent.ACTION_SEND);
            compartirAudio.setType("com.whatsapp");
            compartirAudio.setType("audio/mp3");
            compartirAudio.putExtra(Intent.EXTRA_STREAM,newUri);
            startActivity(Intent.createChooser(compartirAudio, "Compartir vía"));
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(), "Whatsapp no se encuentra instalado", Toast.LENGTH_LONG).show();
        }
    }
});

/////funcion auxiliar/////
private String copyFiletoExternalStorage(int resourceId, String resourceName){
        String pathi= Environment.getExternalStorageDirectory() + "/Android/data/myProject/";
        boolean exists = (new File(pathi)).exists();
        if (!exists) {
            new File(pathi).mkdirs();
        }
        String pathSDCard = Environment.getExternalStorageDirectory() + "/Android/data/TeLoResumoBotonera/" + resourceName;
        try{
            InputStream in = getResources().openRawResource(resourceId);
            FileOutputStream out = null;
            out = new FileOutputStream(pathSDCard);
            byte[] buff = new byte[1024];
            int read = 0;
            try {
                while ((read = in.read(buff)) > 0) {
                    out.write(buff, 0, read);
                }
            } finally {
                in.close();
                out.close();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return  pathSDCard;
    }

/////Elementos agregados al manifest/////

    <queries>

        <package android:name="com.whatsapp" />
        <package android:name="com.whatsapp.w4b" />

    </queries>

    <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.restart.shareaudiofiles.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
    </provider>
</code>```

I researched and implemented various resources to the manifest such as the fileprovider and queries with specific packages for WhatsApp (as can be seen in the code). However, the app still doesn't work. This makes me think that the problem could be in the mobile device that I am using to test the application (I would like to use another one to rule out this option, but I don't have an extra one). If the device has nothing to do with it, then clearly there is a bug in my code. Due to this, in case someone manages to identify the improvement that could make the application work correctly, I would be very grateful if you can share it with me, or at least give me an idea of where to address the problem.

Body:
For some time I've been trying to implement the functionality of sending an audio file from my app through WhatsApp. When debugging everything seems to work correctly in the application, the audio file is generated and saved correctly in the external storage of the device, the WhatsApp window opens and allows me to select the chat to which I want to send the audio. The problem is that when I press the send button, WhatsApp returns the message "Failed to share. Please try again" (I leave a screenshot of the error so that it can be better viewed, in addition to the code used to add said functionality).

Capture of the error shown on the screen by WhatsApp when trying to share the audio:

https://i.stack.imgur.com/gZuLt.jpg

Code used:

//////Boton//////

btn1.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View view) {

        try {
            String mediaPath = copyFiletoExternalStorage(R.raw.audio1, "audio1.mp3");
            File myFile = new File(mediaPath);
            Uri newUri = getUriForFile(wspActivity.this, "com.restart.shareaudiofiles.fileprovider", myFile);
            Intent compartirAudio = new Intent(android.content.Intent.ACTION_SEND);
            compartirAudio.setType("com.whatsapp");
            compartirAudio.setType("audio/mp3");
            compartirAudio.putExtra(Intent.EXTRA_STREAM,newUri);
            startActivity(Intent.createChooser(compartirAudio, "Compartir vía"));
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(), "Whatsapp no se encuentra instalado", Toast.LENGTH_LONG).show();
        }
    }
});

/////funcion auxiliar/////
private String copyFiletoExternalStorage(int resourceId, String resourceName){
        String pathi= Environment.getExternalStorageDirectory() + "/Android/data/myProject/";
        boolean exists = (new File(pathi)).exists();
        if (!exists) {
            new File(pathi).mkdirs();
        }
        String pathSDCard = Environment.getExternalStorageDirectory() + "/Android/data/TeLoResumoBotonera/" + resourceName;
        try{
            InputStream in = getResources().openRawResource(resourceId);
            FileOutputStream out = null;
            out = new FileOutputStream(pathSDCard);
            byte[] buff = new byte[1024];
            int read = 0;
            try {
                while ((read = in.read(buff)) > 0) {
                    out.write(buff, 0, read);
                }
            } finally {
                in.close();
                out.close();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return  pathSDCard;
    }

/////Elementos agregados al manifest/////

    <queries>

        <package android:name="com.whatsapp" />
        <package android:name="com.whatsapp.w4b" />

    </queries>

    <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.restart.shareaudiofiles.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
    </provider>

I researched and implemented various resources to the manifest such as the fileprovider and queries with specific packages for WhatsApp (as can be seen in the code). However, the app still doesn't work. This makes me think that the problem could be in the mobile device that I am using to test the application (I would like to use another one to rule out this option, but I don't have an extra one). If the device has nothing to do with it, then clearly there is a bug in my code. Due to this, in case someone manages to identify the improvement that could make the application work correctly, I would be very grateful if you can share it with me, or at least give me an idea of where to address the problem.


问:
spring kafka consumer is failing to decompress messages [snappy compression]
I am trying to consume messages from kafka using spring-kafka using code below. But I am seeing java.io.IOException: FAILED_TO_UNCOMPRESS(5) error from snappy and org.apache.kafka.common.KafkaException: Failed to decompress record stream

Consumer.java

```<code>  @Autowired
  @Qualifier("batchAckEventProcessor")
  private BatchEventProcessor eventProcessor;

  @KafkaListener(
          topics = "MyAckTopic",
          containerFactory = "kafkaListenerContainerFactory")
  public void consume(Message<Object> message) {
      eventProcessor.process(message.getPayload());
  }
}
</code>```

ConsumerConfig.java

```<code>  public ConsumerFactory<String, JSONObject> batchConsumerConfiguration() {
    Map<String, Object> config = new HashMap<>();
    config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, env.getProperty("batch_kafka_bootstrap_servers_list"));
    config.put(ConsumerConfig.GROUP_ID_CONFIG, env.getProperty("batch_consumer_group_id"));
    config.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    config.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
    return new DefaultKafkaConsumerFactory<>(
        config, new StringDeserializer(), new JsonDeserializer<>(JSONObject.class));
  }

  @Bean
  public ConcurrentKafkaListenerContainerFactory<String, JSONObject> kafkaListenerContainerFactory() {
    ConcurrentKafkaListenerContainerFactory<String, JSONObject> factory =
        new ConcurrentKafkaListenerContainerFactory();
    factory.setConsumerFactory(batchConsumerConfiguration());
    return factory;
  }
</code>```

compression type for topic : snappy

spring boot version : 2.1.1.RELEASE

dependency versions:

```<code>[INFO] +- org.springframework.kafka:spring-kafka:jar:2.2.15.RELEASE:compile
[INFO] |  \- org.apache.kafka:kafka-clients:jar:2.0.1:compile
[INFO] |     +- org.lz4:lz4-java:jar:1.4.1:compile
[INFO] |     \- org.xerial.snappy:snappy-java:jar:1.1.7.1:compile
</code>```

Error log:

```<code>2022-12-20 18:40:01
18:39:58 20-Dec [ERROR] [o.s.kafka.listener.LoggingErrorHandler  ] [handle              :37  ] [] []-> Error while processing: null
2022-12-20 18:40:01
Caused by: org.apache.kafka.common.KafkaException: Failed to decompress record stream
2022-12-20 18:40:01
org.apache.kafka.common.KafkaException: Received exception when fetching the next record from MyAckTopic-0. If needed, please seek past the record to continue consumption.
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecordBatch$1.readNext(DefaultRecordBatch.java:268)
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecordBatch$RecordIterator.next(DefaultRecordBatch.java:563)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.fetchRecords(Fetcher.java:1204)
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecordBatch$RecordIterator.next(DefaultRecordBatch.java:532)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.access$1400(Fetcher.java:1072)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.nextFetchedRecord(Fetcher.java:1183)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchRecords(Fetcher.java:562)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.fetchRecords(Fetcher.java:1218)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchedRecords(Fetcher.java:523)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.access$1400(Fetcher.java:1072)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.KafkaConsumer.pollForFetches(KafkaConsumer.java:1230)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchRecords(Fetcher.java:562)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1187)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchedRecords(Fetcher.java:523)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1154)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.KafkaConsumer.pollForFetches(KafkaConsumer.java:1259)
2022-12-20 18:40:01
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.pollAndInvoke(KafkaMessageListenerContainer.java:757)
2022-12-20 18:40:01
    ... 7 common frames omitted
2022-12-20 18:40:01
Caused by: java.io.IOException: FAILED_TO_UNCOMPRESS(5)
2022-12-20 18:40:01
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:708)
2022-12-20 18:40:01
    at org.xerial.snappy.SnappyNative.throw_error(SnappyNative.java:98)
2022-12-20 18:40:01
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
2022-12-20 18:40:01
    at org.xerial.snappy.SnappyNative.rawUncompress(Native Method)
2022-12-20 18:40:01
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-12-20 18:40:01
    at org.xerial.snappy.Snappy.rawUncompress(Snappy.java:474)
2022-12-20 18:40:01
    at java.lang.Thread.run(Thread.java:748)
2022-12-20 18:40:01
    at org.xerial.snappy.Snappy.uncompress(Snappy.java:513)
2022-12-20 18:40:01
Caused by: org.apache.kafka.common.KafkaException: Failed to decompress record stream
2022-12-20 18:40:01
    at org.xerial.snappy.SnappyInputStream.hasNextChunk(SnappyInputStream.java:439)
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecordBatch$1.readNext(DefaultRecordBatch.java:268)
2022-12-20 18:40:01
    at org.xerial.snappy.SnappyInputStream.read(SnappyInputStream.java:466)
2022-12-20 18:40:01
    at java.io.DataInputStream.readByte(DataInputStream.java:265)
2022-12-20 18:40:01
    at org.apache.kafka.common.utils.ByteUtils.readVarint(ByteUtils.java:168)
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecord.readFrom(DefaultRecord.java:292)
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecordBatch$1.readNext(DefaultRecordBatch.java:264)
2022-12-20 18:40:01
    ... 15 common frames omitted
</code>```

Body:
I am trying to consume messages from kafka using spring-kafka using code below. But I am seeing java.io.IOException: FAILED_TO_UNCOMPRESS(5) error from snappy and org.apache.kafka.common.KafkaException: Failed to decompress record stream

Consumer.java

  @Autowired
  @Qualifier("batchAckEventProcessor")
  private BatchEventProcessor eventProcessor;

  @KafkaListener(
          topics = "MyAckTopic",
          containerFactory = "kafkaListenerContainerFactory")
  public void consume(Message<Object> message) {
      eventProcessor.process(message.getPayload());
  }
}

ConsumerConfig.java

  public ConsumerFactory<String, JSONObject> batchConsumerConfiguration() {
    Map<String, Object> config = new HashMap<>();
    config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, env.getProperty("batch_kafka_bootstrap_servers_list"));
    config.put(ConsumerConfig.GROUP_ID_CONFIG, env.getProperty("batch_consumer_group_id"));
    config.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    config.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
    return new DefaultKafkaConsumerFactory<>(
        config, new StringDeserializer(), new JsonDeserializer<>(JSONObject.class));
  }

  @Bean
  public ConcurrentKafkaListenerContainerFactory<String, JSONObject> kafkaListenerContainerFactory() {
    ConcurrentKafkaListenerContainerFactory<String, JSONObject> factory =
        new ConcurrentKafkaListenerContainerFactory();
    factory.setConsumerFactory(batchConsumerConfiguration());
    return factory;
  }

compression type for topic : snappy

spring boot version : 2.1.1.RELEASE

dependency versions:

[INFO] +- org.springframework.kafka:spring-kafka:jar:2.2.15.RELEASE:compile
[INFO] |  \- org.apache.kafka:kafka-clients:jar:2.0.1:compile
[INFO] |     +- org.lz4:lz4-java:jar:1.4.1:compile
[INFO] |     \- org.xerial.snappy:snappy-java:jar:1.1.7.1:compile

Error log:

2022-12-20 18:40:01
18:39:58 20-Dec [ERROR] [o.s.kafka.listener.LoggingErrorHandler  ] [handle              :37  ] [] []-> Error while processing: null
2022-12-20 18:40:01
Caused by: org.apache.kafka.common.KafkaException: Failed to decompress record stream
2022-12-20 18:40:01
org.apache.kafka.common.KafkaException: Received exception when fetching the next record from MyAckTopic-0. If needed, please seek past the record to continue consumption.
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecordBatch$1.readNext(DefaultRecordBatch.java:268)
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecordBatch$RecordIterator.next(DefaultRecordBatch.java:563)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.fetchRecords(Fetcher.java:1204)
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecordBatch$RecordIterator.next(DefaultRecordBatch.java:532)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.access$1400(Fetcher.java:1072)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.nextFetchedRecord(Fetcher.java:1183)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchRecords(Fetcher.java:562)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.fetchRecords(Fetcher.java:1218)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchedRecords(Fetcher.java:523)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher$PartitionRecords.access$1400(Fetcher.java:1072)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.KafkaConsumer.pollForFetches(KafkaConsumer.java:1230)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchRecords(Fetcher.java:562)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1187)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.internals.Fetcher.fetchedRecords(Fetcher.java:523)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.KafkaConsumer.poll(KafkaConsumer.java:1154)
2022-12-20 18:40:01
    at org.apache.kafka.clients.consumer.KafkaConsumer.pollForFetches(KafkaConsumer.java:1259)
2022-12-20 18:40:01
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.pollAndInvoke(KafkaMessageListenerContainer.java:757)
2022-12-20 18:40:01
    ... 7 common frames omitted
2022-12-20 18:40:01
Caused by: java.io.IOException: FAILED_TO_UNCOMPRESS(5)
2022-12-20 18:40:01
    at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:708)
2022-12-20 18:40:01
    at org.xerial.snappy.SnappyNative.throw_error(SnappyNative.java:98)
2022-12-20 18:40:01
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
2022-12-20 18:40:01
    at org.xerial.snappy.SnappyNative.rawUncompress(Native Method)
2022-12-20 18:40:01
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2022-12-20 18:40:01
    at org.xerial.snappy.Snappy.rawUncompress(Snappy.java:474)
2022-12-20 18:40:01
    at java.lang.Thread.run(Thread.java:748)
2022-12-20 18:40:01
    at org.xerial.snappy.Snappy.uncompress(Snappy.java:513)
2022-12-20 18:40:01
Caused by: org.apache.kafka.common.KafkaException: Failed to decompress record stream
2022-12-20 18:40:01
    at org.xerial.snappy.SnappyInputStream.hasNextChunk(SnappyInputStream.java:439)
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecordBatch$1.readNext(DefaultRecordBatch.java:268)
2022-12-20 18:40:01
    at org.xerial.snappy.SnappyInputStream.read(SnappyInputStream.java:466)
2022-12-20 18:40:01
    at java.io.DataInputStream.readByte(DataInputStream.java:265)
2022-12-20 18:40:01
    at org.apache.kafka.common.utils.ByteUtils.readVarint(ByteUtils.java:168)
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecord.readFrom(DefaultRecord.java:292)
2022-12-20 18:40:01
    at org.apache.kafka.common.record.DefaultRecordBatch$1.readNext(DefaultRecordBatch.java:264)
2022-12-20 18:40:01
    ... 15 common frames omitted


问:
How to call datafile via folder path on a user’s computer in a reactive data call
I am developing a shiny app that is a tool to allow users to map and view photos with the goal of assigning unique ID numbers to unique images in a given area. The tool maps the location of the photos (latitude/longitude) with symbology differentiating photos that have been viewed before (I,e, given a unique ID number and therefore is ‘known’) or have not been viewed yet. Users selectInput attributes about the image (type, color, etc) and the tool filters and displays the photos of all ‘known’ photos based on those attributes; the hope is that if the building has been photographed before, then its previously assessed photos will be displayed including the assigned ID number of that building. The last attribute the user enters is a self-assessment of the photo and whether that building is new to the study (and a new ID number is then assigned) or is already known. If the photo is of a known building, the user enters the ID number of that building. The user then clicks an action button to record and save the data and the map then automatically refreshed with the saved data (hence the previously assessed photo is now known and the symbology updates appropriately).

I want users to be able to practice/learn the app with some supplied practice data as well as be able to upload and use the tool with their own dataset. The file needs to be saved and reloaded regularly so that the map updates and reflects those images that already been assessed. To this end, I have used a reactiveFileReader function to read in the data.  The problem I am facing is defining the file name to alternate between either supplied or user-provided data within the reactiveFileReader call. One other important thing with my app, which I acknowledge is not elegant, is that users need to indicate the folder path to where their data is located both to allow the file to be saved and re-read but also so their photos can be accessed to display. Having users enter their folder path is pretty cumbersome and the requirement they change backslash to forward slash is not ideal but the best I can do at the moment.

The code below seems to function properly except that when users enter their folderpath, the reactive_data call does not seem to actually call the data file despite my checkit which prints the path to the correct file. My thought was that the thefile() call within the reactiveFileReader function is not updating but the two attempts I have in the code have not worked. Any suggestions would be appreciated.

```<code>library(shiny)
library(stringr)
library(shinyFiles)

    # UI ----
ui <- fluidPage(mainPanel(
  p("I don't have my own data, but let me try the tool"),
  actionButton("SampleData", "Let me try the tool!",style="color: #fff; background-color: #1d4568;     border-color: #2e6da4"),
  br(),  br(),  br(),
  p("I have my own data file saved as 'photoID.csv'."),
  p("please copy the path to the folder where your data file resides",strong("BUT we need you to make one change and this
is really important: please change backslash to front slash '/' in the path name."),"We need this information so that as you enter data in the
app, the datafile will save automatically"),
  textInput("folderpath", "Path to folder"),
  h4("My check to see what path is being read:"),
  textOutput("check"), # This prints the correct route to the file...
  h4("Photo data spreadsheet (first few lines)"),
  tableOutput("table_fileR"))
)

    # SERVER ----
server <- function(input, output, session) {

      # FIRST ATTEMPT BUT IT DIDN'T WORK
thefile <- reactive({
  if(nchar(input$folderpath)==0){
    "./data/photoID_Sample.csv"
  }else{
    file.path(paste0(input$folderpath,"/photoID.csv"))
  }
})

      # SECOND ATTEMPT THAT DIDN'T WORK EITHER
      # observe({
      #   invalidateLater(100)
      #   # Do something each time this is invalidated.
      #   thefile <-
      #     if(nchar(input$folderpath)==0){
      #       "./data/photoID_Sample.csv"
      #     }else{
      #       file.path(paste0(input$folderpath,"/photoID.csv"))
      #     }
      # })

      # this is the reactive data set call needed in all outputs and functions in the extended app
reactive_data <- reactiveFileReader(500, session, thefile(), read.csv)

      # Datafile table

observeEvent(input$folderpath, {
  output$table_fileR <-  renderTable({
    if(nchar(input$folderpath)==0){
     return()
    }else{
      dat <- reactive_data()
      return(tail(dat,3)) # Does not update dat with user-supplied data, rather still sample data
      # return(tail(datasets::mtcars,3)) # works as a test when not calling reactive_data()
    }
  })
})

observeEvent(input$SampleData, {
  output$table_fileR <-  renderTable({
    if(is.null(reactive_data())){
      return()
    }else{
      dat <- reactive_data()
      return(head(dat,2)) # works
      #return(head(datasets::Puromycin,2)) # works as a test when not calling reactive_data()
    }
  })
})

    # Path check
observeEvent(c(input$folderpath, input$SampleData), {
   output$check <- renderText({
   checkit <- thefile()
   return(checkit)
    })
  })
}

    # Run the application
shinyApp(ui = ui, server = server)
</code>```

Body:
I am developing a shiny app that is a tool to allow users to map and view photos with the goal of assigning unique ID numbers to unique images in a given area. The tool maps the location of the photos (latitude/longitude) with symbology differentiating photos that have been viewed before (I,e, given a unique ID number and therefore is ‘known’) or have not been viewed yet. Users selectInput attributes about the image (type, color, etc) and the tool filters and displays the photos of all ‘known’ photos based on those attributes; the hope is that if the building has been photographed before, then its previously assessed photos will be displayed including the assigned ID number of that building. The last attribute the user enters is a self-assessment of the photo and whether that building is new to the study (and a new ID number is then assigned) or is already known. If the photo is of a known building, the user enters the ID number of that building. The user then clicks an action button to record and save the data and the map then automatically refreshed with the saved data (hence the previously assessed photo is now known and the symbology updates appropriately).

I want users to be able to practice/learn the app with some supplied practice data as well as be able to upload and use the tool with their own dataset. The file needs to be saved and reloaded regularly so that the map updates and reflects those images that already been assessed. To this end, I have used a reactiveFileReader function to read in the data.  The problem I am facing is defining the file name to alternate between either supplied or user-provided data within the reactiveFileReader call. One other important thing with my app, which I acknowledge is not elegant, is that users need to indicate the folder path to where their data is located both to allow the file to be saved and re-read but also so their photos can be accessed to display. Having users enter their folder path is pretty cumbersome and the requirement they change backslash to forward slash is not ideal but the best I can do at the moment.

The code below seems to function properly except that when users enter their folderpath, the reactive_data call does not seem to actually call the data file despite my checkit which prints the path to the correct file. My thought was that the thefile() call within the reactiveFileReader function is not updating but the two attempts I have in the code have not worked. Any suggestions would be appreciated.

library(shiny)
library(stringr)
library(shinyFiles)

    # UI ----
ui <- fluidPage(mainPanel(
  p("I don't have my own data, but let me try the tool"),
  actionButton("SampleData", "Let me try the tool!",style="color: #fff; background-color: #1d4568;     border-color: #2e6da4"),
  br(),  br(),  br(),
  p("I have my own data file saved as 'photoID.csv'."),
  p("please copy the path to the folder where your data file resides",strong("BUT we need you to make one change and this
is really important: please change backslash to front slash '/' in the path name."),"We need this information so that as you enter data in the
app, the datafile will save automatically"),
  textInput("folderpath", "Path to folder"),
  h4("My check to see what path is being read:"),
  textOutput("check"), # This prints the correct route to the file...
  h4("Photo data spreadsheet (first few lines)"),
  tableOutput("table_fileR"))
)

    # SERVER ----
server <- function(input, output, session) {

      # FIRST ATTEMPT BUT IT DIDN'T WORK
thefile <- reactive({
  if(nchar(input$folderpath)==0){
    "./data/photoID_Sample.csv"
  }else{
    file.path(paste0(input$folderpath,"/photoID.csv"))
  }
})

      # SECOND ATTEMPT THAT DIDN'T WORK EITHER
      # observe({
      #   invalidateLater(100)
      #   # Do something each time this is invalidated.
      #   thefile <-
      #     if(nchar(input$folderpath)==0){
      #       "./data/photoID_Sample.csv"
      #     }else{
      #       file.path(paste0(input$folderpath,"/photoID.csv"))
      #     }
      # })

      # this is the reactive data set call needed in all outputs and functions in the extended app
reactive_data <- reactiveFileReader(500, session, thefile(), read.csv)

      # Datafile table

observeEvent(input$folderpath, {
  output$table_fileR <-  renderTable({
    if(nchar(input$folderpath)==0){
     return()
    }else{
      dat <- reactive_data()
      return(tail(dat,3)) # Does not update dat with user-supplied data, rather still sample data
      # return(tail(datasets::mtcars,3)) # works as a test when not calling reactive_data()
    }
  })
})

observeEvent(input$SampleData, {
  output$table_fileR <-  renderTable({
    if(is.null(reactive_data())){
      return()
    }else{
      dat <- reactive_data()
      return(head(dat,2)) # works
      #return(head(datasets::Puromycin,2)) # works as a test when not calling reactive_data()
    }
  })
})

    # Path check
observeEvent(c(input$folderpath, input$SampleData), {
   output$check <- renderText({
   checkit <- thefile()
   return(checkit)
    })
  })
}

    # Run the application
shinyApp(ui = ui, server = server)


问:
Input [range] Slider Breaks on Mobile when Parent Div has transform:rotate(90deg)
Per the code snippet below, I am trying to create a tool tray with vertical sliders, styled like procreates ui.

When I rotate the tray 90 degrees using transforms to get everything vertical, the sliders break on mobile (any touch device), I can click them to position but pressing and sliding  breaks. If I remove the rotate class, all works fine.

Tested on a wacom touch screen monitor, ipad pro and samsung z fold 3, all touch devices the slider is broken on though works as expected with mouse. Pen devices seem to also break, unable to move the sliders smoothly.

Any help fixing this or a better approach would be greatly welcome, trying to get this to work without javascript

/* Desperate to remove focus outline in firefox */
::-moz-focus-inner {
  outline:0;
}

:focus {
  outline:0;
}

.topcoat-range-input--vertical {
  position: relative;
  /*padding: 0;
  margin: 0;*/
  border: none;
  box-sizing: border-box;
  background-clip: padding-box;
  vertical-align: top;
  outline: none;
  -webkit-appearance: none;

  border-radius: 4px;
  border: 1px solid #a5a8a8;
  background: #CCd3d7d7;
  height: 2rem;
  border-radius: 4px;

}

.topcoat-range-input--vertical::-webkit-slider-thumb{
  cursor: pointer;
  -webkit-appearance: none;
}

.topcoat-range-input--vertical::-moz-range-thumb {
  cursor: pointer;
}

/*.topcoat-range-input--vertical {
  border-radius: 4px;
  border: 1px solid #a5a8a8;
  background: #d3d7d7;
  height: 2rem;
  border-radius: 4px;
}*/

.topcoat-range-input--vertical::-webkit-slider-thumb {
  height: 2rem;
  width: 1.2rem;
  border: 1px solid rgba(0,0,0,0.36);
  border-radius: 6px;
  background: #e5e9e8;
  background-size: 7px 18px;
  box-shadow: inset 0 1px white;
}

.topcoat-range-input--vertical::-moz-range-thumb {

  height: 2rem;
  width: 1.2rem;
  border: 1px solid rgba(0,0,0,0.36);
  border-radius: 6px;
  background: #e5e9e8;
  background-size: 7px 18px;
  box-shadow: inset 0 1px white;

}

::-ms-tooltip,
::-ms-fill-lower {
  display: none;
}

.topcoat-range-input--vertical {

  /*display: block;
  box-sizing: border-box;*/
  vertical-align: middle;

}

#tool-setting-palette{

  background: #000000;
  opacity: 0.8;
  height: fit-content;
  width: fit-content;
  padding: .3em;
  border-radius: 0.5em;

  position: fixed;
  left: 2em;
  bottom: 0;

}

.btn {
  background-color: transparent;
  width: 1.5em;
  height: 1.5em;
  border: none;
  color: white;
  font-size: 1.2em;
  cursor: pointer;
  vertical-align: middle;
}

/* Darker background on mouse-over */
.btn:hover {
  color: RoyalBlue;
}

.btn:active {
  color: Blue;
  transform-origin: center;
  transform:scale(0.9);
}

.rotate-rev-90{
    transform-origin: center left;
  -webkit-transform:rotate(-90deg);
  -moz-transform:rotate(-90deg);
  -ms-transform:rotate(-90deg);
  transform:rotate(-90deg);

}
.rotate-90, .rotate-90 .btn:hover, .rotate-90 .btn:active{

  transform-origin: center;
  -webkit-transform:rotate(90deg);
  -moz-transform:rotate(90deg);
  -ms-transform:rotate(90deg);
  transform:rotate(90deg);
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div id="tool-setting-palette" class="rotate-rev-90">

  <button id="redo-btn" type="button" value="" class="btn rotate-90"><i class="fa fa-repeat"></i></button>

  <button id="undo-btn" type="button" value="" class="btn rotate-90"><i class="fa fa-undo"></i></button>

  <input type='range'   class='topcoat-range-input--vertical'>

  <input type='range'   class='topcoat-range-input--vertical'>

</div></code>```

https://codepen.io/taibhse-designs/pen/zYLxvOj

Body:
Per the code snippet below, I am trying to create a tool tray with vertical sliders, styled like procreates ui.

When I rotate the tray 90 degrees using transforms to get everything vertical, the sliders break on mobile (any touch device), I can click them to position but pressing and sliding  breaks. If I remove the rotate class, all works fine.

Tested on a wacom touch screen monitor, ipad pro and samsung z fold 3, all touch devices the slider is broken on though works as expected with mouse. Pen devices seem to also break, unable to move the sliders smoothly.

Any help fixing this or a better approach would be greatly welcome, trying to get this to work without javascript

/* Desperate to remove focus outline in firefox */
::-moz-focus-inner {
  outline:0;
}

:focus {
  outline:0;
}

.topcoat-range-input--vertical {
  position: relative;
  /*padding: 0;
  margin: 0;*/
  border: none;
  box-sizing: border-box;
  background-clip: padding-box;
  vertical-align: top;
  outline: none;
  -webkit-appearance: none;

  border-radius: 4px;
  border: 1px solid #a5a8a8;
  background: #CCd3d7d7;
  height: 2rem;
  border-radius: 4px;

}

.topcoat-range-input--vertical::-webkit-slider-thumb{
  cursor: pointer;
  -webkit-appearance: none;
}

.topcoat-range-input--vertical::-moz-range-thumb {
  cursor: pointer;
}

/*.topcoat-range-input--vertical {
  border-radius: 4px;
  border: 1px solid #a5a8a8;
  background: #d3d7d7;
  height: 2rem;
  border-radius: 4px;
}*/

.topcoat-range-input--vertical::-webkit-slider-thumb {
  height: 2rem;
  width: 1.2rem;
  border: 1px solid rgba(0,0,0,0.36);
  border-radius: 6px;
  background: #e5e9e8;
  background-size: 7px 18px;
  box-shadow: inset 0 1px white;
}

.topcoat-range-input--vertical::-moz-range-thumb {

  height: 2rem;
  width: 1.2rem;
  border: 1px solid rgba(0,0,0,0.36);
  border-radius: 6px;
  background: #e5e9e8;
  background-size: 7px 18px;
  box-shadow: inset 0 1px white;

}

::-ms-tooltip,
::-ms-fill-lower {
  display: none;
}

.topcoat-range-input--vertical {

  /*display: block;
  box-sizing: border-box;*/
  vertical-align: middle;

}

#tool-setting-palette{

  background: #000000;
  opacity: 0.8;
  height: fit-content;
  width: fit-content;
  padding: .3em;
  border-radius: 0.5em;

  position: fixed;
  left: 2em;
  bottom: 0;

}

.btn {
  background-color: transparent;
  width: 1.5em;
  height: 1.5em;
  border: none;
  color: white;
  font-size: 1.2em;
  cursor: pointer;
  vertical-align: middle;
}

/* Darker background on mouse-over */
.btn:hover {
  color: RoyalBlue;
}

.btn:active {
  color: Blue;
  transform-origin: center;
  transform:scale(0.9);
}

.rotate-rev-90{
    transform-origin: center left;
  -webkit-transform:rotate(-90deg);
  -moz-transform:rotate(-90deg);
  -ms-transform:rotate(-90deg);
  transform:rotate(-90deg);

}
.rotate-90, .rotate-90 .btn:hover, .rotate-90 .btn:active{

  transform-origin: center;
  -webkit-transform:rotate(90deg);
  -moz-transform:rotate(90deg);
  -ms-transform:rotate(90deg);
  transform:rotate(90deg);
}

  <button id="redo-btn" type="button" value="" class="btn rotate-90"></button>

  <button id="undo-btn" type="button" value="" class="btn rotate-90"></button>

  <input type='range'   class='topcoat-range-input--vertical'>

  <input type='range'   class='topcoat-range-input--vertical'>

https://codepen.io/taibhse-designs/pen/zYLxvOj


问:
i need to find logic to add new table for sequelize in node js
user table

id: 1 , name: messi;

id: 2 , name: Alex;

room table

id 1, name: song;

id: 2, name: game;

chat data

userId:  2, first_seen: 1671471509, roomId: 1;

userId:  2, first_seen: 1671471510, roomId: 1;

userId:  2, first_seen: 167147151, roomId: 2;

new table I want to create this

userId:  2, first_seen: 1671471509, last_seen: 167147151, roomId: 1;

Alex was in the singing room on 1671471509. He was in the singing room on 1671471510, he was in the game room on 167147151.

Alex seen for the first time in the singing room 1671471509,

that was the last time he was seen 167147151,

because when he moved to another room, the previous room was seen for the last time.

I want to create a new table and print the first and last seen of users in the room

how can I do that?


问:
using Tooltip in a Modal Component unsing ReactStrap
I have a Modal component in my project and I need to show a Tooltip when my mouse pass over a link that is in the modal, the thing is that de Tooltip does not show when i use de same code in a component that is not a Modal works fine.

How can I show that tooltip into the modal?


问:
prefix of string accepted by an FSA
I have an unweighted finite state acceptor (FSA), and a sequence of symbols. I want to check if this symbol sequence is a prefix of a symbol sequence accepted by the FSA.

There could be <eps> transitions in the FSA. And I don't think this is a simple matter of calling fstcompose (like here), as we are dealing with prefix.

One hack I can think of is to modify the FSA such that each state is a final state. Then the prefix of an accepted string can now be accepted by the modified FSA. But any other idea?

Title: prefix of string accepted by an FSA


问:
Can't upload transformed images. It only uploads the original images
I have implemented the Image Transform plugin in order to compress all images. It does seem to transform the image that I add to FilePond. But, when the file is actually submitted to be uploaded to our server, it submits the original untransformed image.

```<code>import React, {useEffect, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import WishlistPage from '../../WishlistPage';
import { useUserContext } from '@magento/peregrine/lib/context/user';
import { FilePond } from 'react-filepond';
import { useDesignCenter } from './useDesignCenter.js';
import LoadingIndicator from '@magento/venia-ui/lib/components/LoadingIndicator';

const DesignCenter = () => {
const [files, _setFiles] = useState([]);
const [responseText, setResponseText] = useState("");
const [validateField, setValidateField] = useState("");
const [activeAlbum, _setActiveAlbum] = useState(-1);
const { albumData, albumLoading, albumError, refetch } = useDesignCenter();

    var datacmpdatalayer ='{"button-roomPlannerBtn":{"id"="signupModalBtn","@type":"core/wcm/components/button/v2/button","dc:title":"roomPlannerBtn"}}';

    const filesRef = React.useRef(files);
    const setFiles = data => {
        filesRef.current = data;
        _setFiles(data);
    };

    const [{ isSignedIn }] = useUserContext();
    if (!isSignedIn) {
        return <span>Please login to continue.</span>;
    }

    const validatePhotos = value => {
        if (value == null || value.length == 0) {
            setResponseText("Please Upload Photos");
            return false;
        }
        return true;
    }
    const validateAlbumName = value => {
        if (value == null || value == "") {
            setValidateField("is Required");
            return false;
        }
        return true;
    }

    const validateFields = (photos, albumName) => {
        const photosTest =  validatePhotos(photos);
        const albumTest = validateAlbumName(albumName);
        if(photosTest && albumTest){
            return true;
        }
        return false;
    }

    const handleError = (error) => {
        console.error(error);
        document.querySelector('#uploadphotoalbum-dialog .cmp-button').removeAttribute('disabled');
    }

    const submitAlbum = () =>{
        const formData = new FormData();
        const albumName = document.querySelector('#new-album-name').value;
        const username = albumData.customer.hvt_emails[0].email;

        formData.append("email", username);
        formData.append("albumName", albumName);

        const photoFiles = filesRef.current;
        photoFiles.forEach((photoFile) => {
            formData.append("images", photoFile.file);
        })
        var csrfUrl = window.location.origin + '/libs/granite/csrf/token.json';
        if (validateFields(photoFiles, albumName)){
            document.querySelector('#uploadphotoalbum-dialog .cmp-button').setAttribute('disabled', 'disabled');
            fetch(csrfUrl)
                .then(response => response.json())
                .then(data => {
                    const csrfToken = data.token;
                    fetch(window.location.pathname.replace('.html', '') + '.create-album.json', {
                        method: 'POST',
                        headers: {
                            'CSRF-Token': csrfToken
                        },
                        mode: 'cors',
                        cache: 'no-cache',
                        body: formData
                    })

                        .then((response) => {
                            if (response.ok) {
                                hvtDialog.close('uploadphotoalbum-dialog');
                                refetch()
                                document.getElementById("new-album-name").value = '';
                                setFiles(null)
                            } else {
                                document.querySelector('#uploadphotoalbum-dialog .cmp-button').removeAttribute('disabled');
                            }
                        })
                        .catch(error => handleError(error));
                })
                .catch(error => handleError(error));
            }
        }

    useEffect(() => {
        const photosElement = document.querySelector(`.open-album`);
        const albumElements = document.querySelectorAll(`.designCenter__album`);
        if(albumElements){
            albumElements.forEach(albumElement => {
                albumElement.style.marginBottom = 0 +"px";
            })
        }
        if(photosElement){
            photosElement.parentNode.style.marginBottom= photosElement.offsetHeight + "px";
         }
    }, [activeAlbum])

    if (albumLoading){
        return <LoadingIndicator />;
    }

    if (albumError){
        console.error(albumError);
        return <p>There was an error retrieving your albums.</p>;
    }

    const uploadPhotoAlbum = () => {
        hvtDialog.open('uploadphotoalbum-dialog', {
            heading: 'Upload New Album',
            maxHeight: '80vh',
            overlay: true,
            buttons: [
                {
                    text: "Create Album",
                }
            ]
        });
        document.querySelector('#uploadphotoalbum-dialog .cmp-button').addEventListener('click', submitAlbum);
    };

    const toggleAccordion = (e) => {
        var target = e.currentTarget
        if(target.classList.contains('cmp-accordion')) {
            const nodes = document.getElementsByClassName('cmp-accordion')
            for(var node of nodes) {
                if(node.hasAttribute('open') && node !== e.currentTarget) {
                    node.removeAttribute('open')
                }
            }
        }
    }

const viewPhotoAlbum = (albumId) =>{
if(albumId == activeAlbum){
_setActiveAlbum(-1);
} else{
_setActiveAlbum(albumId);
}
}

const viewPhoto = (event) => {
var thisPhoto = event.target.cloneNode(true);
thisPhoto.style.width = "100%";
hvtDialog.open('designCenter__photo-viewer', {
content: thisPhoto,
width: '90vw',
maxWidth: '1000px',
overlay: true,
position: {
relative: true,
relativeToWindow: true,
top: '20px',
centerY: false
}
});
};

    const handlePhotoDelete = (eMediaId, index) =>{
        var csrfUrl = window.location.origin + '/libs/granite/csrf/token.json';
        fetch(csrfUrl)
            .then(response => response.json())
            .then(data => {
                const csrfToken = data.token;

                fetch(window.location.pathname.replace('.html', '') + '.deletemedia.json?mediaId='+ eMediaId, {
                    method: 'POST',
                    headers: {
                        'CSRF-Token': csrfToken
                    },
                    mode: 'cors',
                    cache: 'no-cache',
                })

                .then((response) => {
                    if (response.ok) {
                        refetch()
                    } else {
                        error => handleError(error)
                    }
                })
                .catch(error => handleError(error));
        })
        .catch(error => handleError(error));
    }

    return (
        <div className="designCenter">

            <div className="designCenter__photoalbums">
                <details className="cmp-photoalbums cmp-accordion" onClick={toggleAccordion}>
                    <summary>
                        <span className="cmp-accordion__flex-container">
                            <h2><FormattedMessage id={'photoalbums.heading'} defaultMessage={'My Photo Albums'} /></h2>
                        </span>
                    </summary>
                    <div className="designCenter__photos">
                        {albumData.customer.albums.map((album, index) => (
                            <div className="cmp-photoalbums__album designCenter__album" key={index}>
                             <button className="designCenter__button" id={`cover-${index}`} onClick={()=>{
                                    viewPhotoAlbum(index)
                                    }}>
                                 <img className= {`designCenter__photo ${activeAlbum == index ? `active ` : "" }` } src={album.photos[0].media_url}/>
                             </button>
                             <h6 className={`designCenter__album-title ${activeAlbum == index ? `open-album-arrow ` : "" }` }>{album.album_name}</h6>
                             <div onChange={(event)=>{ console.log(event) }}
                             className={`cmp-photoalbums__photoslist ${activeAlbum == index ? `open-album ` : "" }` }  id={`album-${index}`}>
                             {album.photos.map((photo) => (
                                 <div key={photo.e_media_id} className="designCenter__photoalbums-photo" id={`photo-${photo.e_media_id}`}>
                                    <button onClick={viewPhoto}>
                                        <img className="designCenter__photoalbums-photo" src={photo.media_url}/>
                                    </button>
                                    <button className="designCenter__photoalbums-trash" onClick={()=>handlePhotoDelete(photo.e_media_id, index)}></button>
                                </div>
                             ))}
                             <button className="designCenter__close" onClick={()=>{
                                     _setActiveAlbum(-1);
                                     document.getElementById(`cover-${index}`).classList.remove("active");}}>
                             </button>
                             </div>
                            </div>
                        ))
                        }
                        <div className="cmp-photoalbums__upload">
                            <button onClick={uploadPhotoAlbum}>
                                <FormattedMessage id={'photoalbums.upload'} defaultMessage={'Upload New Album'} />
                            </button>
                        </div>
                    </div>
                    <div className="designCenter__photo-viewer hvt-dialog" id="designCenter__photo-viewer"></div>
                    <div id="uploadphotoalbum-dialog" className="hvt-dialog cmp-photoalbums__modal">
                        <p>Our design team is excited to start a project with you! Check out our guidelines below to ensure your photos are formatted correctly.</p>
                        <ul className="cmp-photoalbums__guide">
                            <li>Make sure at least two walls are visible.</li>
                            <li>Keep both the floor and ceiling visible.</li>
                            <li>For best results, use high resolution photos.</li>
                        </ul>
                        <label htmlFor="new-album-name">Album name</label>
                        <input
                            id="new-album-name"
                            className={validateField ? "field__input designCenter__fieldInput cmp-TextInput__textInput__input_error" : "field__input designCenter__fieldInput"}
                            maxLength={50}
                            />
                        <p className="cmp-Field__message__root_error">{validateField}</p>
                        <div id="filepond__app" className={responseText ? "designCenter__filePond designCenter__filePond-error" : "designCenter__filePond"}>
                            <FilePond
                                files={files}
                                allowMultiple={true}
                                allowFileTypeValidation={true}
                                allowFileSizeValidation={true}
                                allowImageExifOrientation={true}
                                imageTransformOutputQuality={70}
                                labelIdle="<div class='upload-icon filepond--label-action'></div>Drag & drop files or <span class='filepond--label-action'>browse</span><p class='filepond--sublabel'>Supports: JPG, JPEG2000, PNG</p>"
                                labelFileProcessing="Uploading..."
                                acceptedFileTypes={['image/png', 'image/jpeg']}
                                labelFileTypeNotAllowed="File type not valid."
                                fileValidateTypeLabelExpectedTypes="Only upload valid PNG, JPEG image and PDF files"
                                maxFileSize={5000000}
                                storeAsFile={true}
                                labelMaxFileSizeExceeded="File is too large"
                                labelMaxFileSize="Maximum file size is 5MB"
                                labelFileProcessingError="Upload Error"
                                labelFileProcessingComplete="Completed"
                                maxFiles={10}
                                server={{
                                    process: (fieldName, file, metadata, load) => {
                                        load();
                                    }
                                }}
                                onupdatefiles={setFiles}
                                styleItemPanelAspectRatio={0.1}
                                styleButtonRemoveItemPosition={'right'}
                                credits={false}
                            />
                        </div>
                        <p className="cmp-Field__message__root_error">{responseText}</p>
                    </div>
                </details>
            </div>
        </div>
    );

};

export default DesignCenter;
</code>```

I'm expecting that when I click "Create Album" it will upload the transformed (compressed) image instead of the original.

Body:
I have implemented the Image Transform plugin in order to compress all images. It does seem to transform the image that I add to FilePond. But, when the file is actually submitted to be uploaded to our server, it submits the original untransformed image.

import React, {useEffect, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import WishlistPage from '../../WishlistPage';
import { useUserContext } from '@magento/peregrine/lib/context/user';
import { FilePond } from 'react-filepond';
import { useDesignCenter } from './useDesignCenter.js';
import LoadingIndicator from '@magento/venia-ui/lib/components/LoadingIndicator';

const DesignCenter = () => {
const [files, _setFiles] = useState([]);
const [responseText, setResponseText] = useState("");
const [validateField, setValidateField] = useState("");
const [activeAlbum, _setActiveAlbum] = useState(-1);
const { albumData, albumLoading, albumError, refetch } = useDesignCenter();

    var datacmpdatalayer ='{"button-roomPlannerBtn":{"id"="signupModalBtn","@type":"core/wcm/components/button/v2/button","dc:title":"roomPlannerBtn"}}';

    const filesRef = React.useRef(files);
    const setFiles = data => {
        filesRef.current = data;
        _setFiles(data);
    };

    const [{ isSignedIn }] = useUserContext();
    if (!isSignedIn) {
        return Please login to continue.;
    }

    const validatePhotos = value => {
        if (value == null || value.length == 0) {
            setResponseText("Please Upload Photos");
            return false;
        }
        return true;
    }
    const validateAlbumName = value => {
        if (value == null || value == "") {
            setValidateField("is Required");
            return false;
        }
        return true;
    }

    const validateFields = (photos, albumName) => {
        const photosTest =  validatePhotos(photos);
        const albumTest = validateAlbumName(albumName);
        if(photosTest && albumTest){
            return true;
        }
        return false;
    }

    const handleError = (error) => {
        console.error(error);
        document.querySelector('#uploadphotoalbum-dialog .cmp-button').removeAttribute('disabled');
    }

    const submitAlbum = () =>{
        const formData = new FormData();
        const albumName = document.querySelector('#new-album-name').value;
        const username = albumData.customer.hvt_emails[0].email;

        formData.append("email", username);
        formData.append("albumName", albumName);

        const photoFiles = filesRef.current;
        photoFiles.forEach((photoFile) => {
            formData.append("images", photoFile.file);
        })
        var csrfUrl = window.location.origin + '/libs/granite/csrf/token.json';
        if (validateFields(photoFiles, albumName)){
            document.querySelector('#uploadphotoalbum-dialog .cmp-button').setAttribute('disabled', 'disabled');
            fetch(csrfUrl)
                .then(response => response.json())
                .then(data => {
                    const csrfToken = data.token;
                    fetch(window.location.pathname.replace('.html', '') + '.create-album.json', {
                        method: 'POST',
                        headers: {
                            'CSRF-Token': csrfToken
                        },
                        mode: 'cors',
                        cache: 'no-cache',
                        body: formData
                    })

                        .then((response) => {
                            if (response.ok) {
                                hvtDialog.close('uploadphotoalbum-dialog');
                                refetch()
                                document.getElementById("new-album-name").value = '';
                                setFiles(null)
                            } else {
                                document.querySelector('#uploadphotoalbum-dialog .cmp-button').removeAttribute('disabled');
                            }
                        })
                        .catch(error => handleError(error));
                })
                .catch(error => handleError(error));
            }
        }

    useEffect(() => {
        const photosElement = document.querySelector(`.open-album`);
        const albumElements = document.querySelectorAll(`.designCenter__album`);
        if(albumElements){
            albumElements.forEach(albumElement => {
                albumElement.style.marginBottom = 0 +"px";
            })
        }
        if(photosElement){
            photosElement.parentNode.style.marginBottom= photosElement.offsetHeight + "px";
         }
    }, [activeAlbum])

    if (albumLoading){
        return <LoadingIndicator />;
    }

    if (albumError){
        console.error(albumError);
        return
There was an error retrieving your albums.
;
    }

    const uploadPhotoAlbum = () => {
        hvtDialog.open('uploadphotoalbum-dialog', {
            heading: 'Upload New Album',
            maxHeight: '80vh',
            overlay: true,
            buttons: [
                {
                    text: "Create Album",
                }
            ]
        });
        document.querySelector('#uploadphotoalbum-dialog .cmp-button').addEventListener('click', submitAlbum);
    };

    const toggleAccordion = (e) => {
        var target = e.currentTarget
        if(target.classList.contains('cmp-accordion')) {
            const nodes = document.getElementsByClassName('cmp-accordion')
            for(var node of nodes) {
                if(node.hasAttribute('open') && node !== e.currentTarget) {
                    node.removeAttribute('open')
                }
            }
        }
    }

const viewPhotoAlbum = (albumId) =>{
if(albumId == activeAlbum){
_setActiveAlbum(-1);
} else{
_setActiveAlbum(albumId);
}
}

const viewPhoto = (event) => {
var thisPhoto = event.target.cloneNode(true);
thisPhoto.style.width = "100%";
hvtDialog.open('designCenter__photo-viewer', {
content: thisPhoto,
width: '90vw',
maxWidth: '1000px',
overlay: true,
position: {
relative: true,
relativeToWindow: true,
top: '20px',
centerY: false
}
});
};

    const handlePhotoDelete = (eMediaId, index) =>{
        var csrfUrl = window.location.origin + '/libs/granite/csrf/token.json';
        fetch(csrfUrl)
            .then(response => response.json())
            .then(data => {
                const csrfToken = data.token;

                fetch(window.location.pathname.replace('.html', '') + '.deletemedia.json?mediaId='+ eMediaId, {
                    method: 'POST',
                    headers: {
                        'CSRF-Token': csrfToken
                    },
                    mode: 'cors',
                    cache: 'no-cache',
                })

                .then((response) => {
                    if (response.ok) {
                        refetch()
                    } else {
                        error => handleError(error)
                    }
                })
                .catch(error => handleError(error));
        })
        .catch(error => handleError(error));
    }

    return (

<FormattedMessage id={'photoalbums.heading'} defaultMessage={'My Photo Albums'} />

                        {albumData.customer.albums.map((album, index) => (

                             <button className="designCenter__button" id={`cover-${index}`} onClick={()=>{
                                    viewPhotoAlbum(index)
                                    }}>
                                 <img className= {`designCenter__photo ${activeAlbum == index ? `active ` : "" }` } src={album.photos[0].media_url}/>
                             </button>
                             <h6 className={`designCenter__album-title ${activeAlbum == index ? `open-album-arrow ` : "" }` }>{album.album_name}

{ console.log(event) }}
                             className={`cmp-photoalbums__photoslist ${activeAlbum == index ? `open-album ` : "" }` }  id={`album-${index}`}>
                             {album.photos.map((photo) => (
                                 <div key={photo.e_media_id} className="designCenter__photoalbums-photo" id={`photo-${photo.e_media_id}`}>
                                    <button onClick={viewPhoto}>

                                    </button>
                                    <button className="designCenter__photoalbums-trash" onClick={()=>handlePhotoDelete(photo.e_media_id, index)}></button>

                             ))}
                             <button className="designCenter__close" onClick={()=>{
                                     _setActiveAlbum(-1);
                                     document.getElementById(`cover-${index}`).classList.remove("active");}}>
                             </button>

                        ))
                        }

                            <button onClick={uploadPhotoAlbum}>
                                <FormattedMessage id={'photoalbums.upload'} defaultMessage={'Upload New Album'} />
                            </button>

Our design team is excited to start a project with you! Check out our guidelines below to ensure your photos are formatted correctly.

Make sure at least two walls are visible.

Keep both the floor and ceiling visible.

For best results, use high resolution photos.

                        Album name
                        <input
                            id="new-album-name"
                            className={validateField ? "field__input designCenter__fieldInput cmp-TextInput__textInput__input_error" : "field__input designCenter__fieldInput"}
                            maxLength={50}
                            />

{validateField}

                            <FilePond
                                files={files}
                                allowMultiple={true}
                                allowFileTypeValidation={true}
                                allowFileSizeValidation={true}
                                allowImageExifOrientation={true}
                                imageTransformOutputQuality={70}
                                labelIdle="

Drag & drop files or browse
Supports: JPG, JPEG2000, PNG
"
                                labelFileProcessing="Uploading..."
                                acceptedFileTypes={['image/png', 'image/jpeg']}
                                labelFileTypeNotAllowed="File type not valid."
                                fileValidateTypeLabelExpectedTypes="Only upload valid PNG, JPEG image and PDF files"
                                maxFileSize={5000000}
                                storeAsFile={true}
                                labelMaxFileSizeExceeded="File is too large"
                                labelMaxFileSize="Maximum file size is 5MB"
                                labelFileProcessingError="Upload Error"
                                labelFileProcessingComplete="Completed"
                                maxFiles={10}
                                server={{
                                    process: (fieldName, file, metadata, load) => {
                                        load();
                                    }
                                }}
                                onupdatefiles={setFiles}
                                styleItemPanelAspectRatio={0.1}
                                styleButtonRemoveItemPosition={'right'}
                                credits={false}
                            />

{responseText}

    );

};

export default DesignCenter;

I'm expecting that when I click "Create Album" it will upload the transformed (compressed) image instead of the original.


问:
getting 404 when access to laravel horizon dashboard
I am using laravel with docker and redis and now I am trying to use horizon for the queues.

Docker-compose file:

```<code>  ### PHP Container #########################################   findra-nadal:
    container_name: findra_nadal
    hostname: nadal
    build:
      context: ./nadal
      dockerfile: Dockerfile
    restart: unless-stopped
    working_dir: /var/www
    volumes:
      - ./nadal:/var/www/
    depends_on:
      - findra-db
      - findra-db-test
      - findra-redis

  ### NGINX Container #########################################   findra-nginx:
    container_name: findra_nginx
    hostname: nginx
    image: nginx:1.21
    restart: unless-stopped
    depends_on:
      - findra-nadal
      - findra-minio
    ports:
      - "5001:80"
    volumes:
      - ./nadal/docker/virtualhost.conf:/etc/nginx/conf.d/default.conf
### Redis Container #########################################   findra-redis:
    container_name: findra_redis
    image: 'redis:alpine'
    ports:
      - '${FORWARD_REDIS_PORT:-6379}:6379'
    volumes:
      - redis-data:/data
    healthcheck:
            test: ["CMD", "redis-cli", "ping"]
            retries: 3
            timeout: 5s
</code>```

Then I executed

composer require laravel/horizon

php artisan horizon:install

And when I tried to access to horizon I have problem with css files.

URL: http://localhost:5001/horizon

Body:
I am using laravel with docker and redis and now I am trying to use horizon for the queues.

Docker-compose file:

  ### PHP Container #########################################   findra-nadal:
    container_name: findra_nadal
    hostname: nadal
    build:
      context: ./nadal
      dockerfile: Dockerfile
    restart: unless-stopped
    working_dir: /var/www
    volumes:
      - ./nadal:/var/www/
    depends_on:
      - findra-db
      - findra-db-test
      - findra-redis

  ### NGINX Container #########################################   findra-nginx:
    container_name: findra_nginx
    hostname: nginx
    image: nginx:1.21
    restart: unless-stopped
    depends_on:
      - findra-nadal
      - findra-minio
    ports:
      - "5001:80"
    volumes:
      - ./nadal/docker/virtualhost.conf:/etc/nginx/conf.d/default.conf
### Redis Container #########################################   findra-redis:
    container_name: findra_redis
    image: 'redis:alpine'
    ports:
      - '${FORWARD_REDIS_PORT:-6379}:6379'
    volumes:
      - redis-data:/data
    healthcheck:
            test: ["CMD", "redis-cli", "ping"]
            retries: 3
            timeout: 5s

Then I executed

composer require laravel/horizon

php artisan horizon:install

And when I tried to access to horizon I have problem with css files.

URL: http://localhost:5001/horizon


问:
Storybook: Can't resolve 'next-i18next/serverSideTranslations'
I have the next-i18next in my Next.js Project. And also add the storybook to my project.

When I try to add the story for the home page. I got error
Module not found: Error: Can't resolve 'next-i18next/serverSideTranslations' in "xxxx\xxx\"

When I remove export const getStaticProps , the storybook works fine.

How to resolve this issue.

The following are my configurations

This is the translation in level 1 page.

```<code>import {serverSideTranslations} from 'next-i18next/serverSideTranslations'

export const getStaticProps = async ({locale}) => ({
  props: {
    ...await serverSideTranslations(locale, ['index']),
  },
})
</code>```

.storybook/main.js

```<code>const path = require('path')

module.exports = {
  "stories": [
    "../src/**/*.stories.mdx",
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
    {
      name: 'storybook-addon-next',
      options: {
        nextConfigPath: path.resolve(__dirname, '../next.config.js')
      }
    }
  ],
  staticDirs: ['../public'],
  "framework": "@storybook/react",
  core: {
    builder: '@storybook/builder-webpack5'
  },
  webpackFinal: async (config, {configType}) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      "@": path.resolve(__dirname, "../src/"),
      'next-i18next': 'react-i18next'
    };
    config.resolve.modules = [path.resolve(__dirname, '..'), 'node_modules'];

    // this modifies the existing image rule to exclude .svg files
    // since we want to handle those files with @svgr/webpack
    const imageRule = config.module.rules.find(rule => rule.test.test('.svg'))
    imageRule.exclude = /\.svg$/

    // configure .svg files to be loaded with @svgr/webpack
    config.module.rules.push({
      test: /\.svg$/,
      use: ['@svgr/webpack']
    })

    // Return the altered config
    return config;
  },
  typescript: {
    check: true, // type-check stories during Storybook build
  }
}
</code>```

.storybook/preview.js

```<code>//reset styles
import '../src/assets/styles/common.css'
import '../src/assets/styles/reset.css'
import '../src/assets/styles/other.scss'
//add antd style
import 'antd/dist/antd.css'
import React, {Suspense, useEffect} from "react";
import { initReactI18next, I18nextProvider } from 'react-i18next'
// import i18n from './i18n';
import i18next from 'i18next'
import * as NextImage from "next/image";
import { CUSTOM_VIEWPORTS } from './viewports'
import HttpApi from 'i18next-http-backend';

const OriginalNextImage = NextImage.default;

Object.defineProperty(NextImage, "default", {
  configurable: true,
  value: (props) => <OriginalNextImage {...props} unoptimized/>,
});
export const parameters = {
  actions: {argTypesRegex: "^on[A-Z].*"},
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
    expanded: true
  },
  viewport: {
    viewports: CUSTOM_VIEWPORTS,
  },
  storySort: {
    method: 'alphabetical',
    order: ['Common', 'Ant Design', 'Others'],
  },
}
// Create a global variable called locale in storybook
// and add a menu in the toolbar to change your locale
export const globalTypes = {
  locale: {
    name: 'Locale',
    description: 'Internationalization locale',
    toolbar: {
      icon: 'globe',
      items: [
        {value: 'En', title: 'English'},
        {value: 'Fr', title: 'French'},
      ],
      showName: true,
    },
  },
};

// Wrap your stories in the I18nextProvider component
const i18nextStoryDecorator = (Story, context) => {
  const { locale } = context.globals;

  i18next
    .use(HttpApi)
    .use(initReactI18next)
    .init({
      whitelist:['En','Fr'],
      lng: locale,
      fallbackLng: 'En',
      ns: 'index',
      defaultNS: 'index',
      defaultLocale: "En",
      debug: true,
    })
  // When the locale global changes
  // Set the new locale in i18n
  useEffect(() => {
    i18next.changeLanguage(locale);
  }, [locale]);

  return (
    // here catches the suspense from components not yet ready (still loading translations)
    // alternative set useSuspense false on i18next.options.react when initializing i18next
    <Suspense fallback={<div>loading translations...</div>}>
      <I18nextProvider i18n={i18next}>
        <Story />
      </I18nextProvider>
    </Suspense>
  );
};

// export decorators for storybook to wrap your stories in
export const decorators = [i18nextStoryDecorator];
</code>```

Body:
I have the next-i18next in my Next.js Project. And also add the storybook to my project.

When I try to add the story for the home page. I got error
Module not found: Error: Can't resolve 'next-i18next/serverSideTranslations' in "xxxx\xxx\"

When I remove export const getStaticProps , the storybook works fine.

How to resolve this issue.

The following are my configurations

This is the translation in level 1 page.

import {serverSideTranslations} from 'next-i18next/serverSideTranslations'

export const getStaticProps = async ({locale}) => ({
  props: {
    ...await serverSideTranslations(locale, ['index']),
  },
})

.storybook/main.js

const path = require('path')

module.exports = {
  "stories": [
    "../src/**/*.stories.mdx",
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
    {
      name: 'storybook-addon-next',
      options: {
        nextConfigPath: path.resolve(__dirname, '../next.config.js')
      }
    }
  ],
  staticDirs: ['../public'],
  "framework": "@storybook/react",
  core: {
    builder: '@storybook/builder-webpack5'
  },
  webpackFinal: async (config, {configType}) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      "@": path.resolve(__dirname, "../src/"),
      'next-i18next': 'react-i18next'
    };
    config.resolve.modules = [path.resolve(__dirname, '..'), 'node_modules'];

    // this modifies the existing image rule to exclude .svg files
    // since we want to handle those files with @svgr/webpack
    const imageRule = config.module.rules.find(rule => rule.test.test('.svg'))
    imageRule.exclude = /\.svg$/

    // configure .svg files to be loaded with @svgr/webpack
    config.module.rules.push({
      test: /\.svg$/,
      use: ['@svgr/webpack']
    })

    // Return the altered config
    return config;
  },
  typescript: {
    check: true, // type-check stories during Storybook build
  }
}

.storybook/preview.js

//reset styles
import '../src/assets/styles/common.css'
import '../src/assets/styles/reset.css'
import '../src/assets/styles/other.scss'
//add antd style
import 'antd/dist/antd.css'
import React, {Suspense, useEffect} from "react";
import { initReactI18next, I18nextProvider } from 'react-i18next'
// import i18n from './i18n';
import i18next from 'i18next'
import * as NextImage from "next/image";
import { CUSTOM_VIEWPORTS } from './viewports'
import HttpApi from 'i18next-http-backend';

const OriginalNextImage = NextImage.default;

Object.defineProperty(NextImage, "default", {
  configurable: true,
  value: (props) => <OriginalNextImage {...props} unoptimized/>,
});
export const parameters = {
  actions: {argTypesRegex: "^on[A-Z].*"},
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
    expanded: true
  },
  viewport: {
    viewports: CUSTOM_VIEWPORTS,
  },
  storySort: {
    method: 'alphabetical',
    order: ['Common', 'Ant Design', 'Others'],
  },
}
// Create a global variable called locale in storybook
// and add a menu in the toolbar to change your locale
export const globalTypes = {
  locale: {
    name: 'Locale',
    description: 'Internationalization locale',
    toolbar: {
      icon: 'globe',
      items: [
        {value: 'En', title: 'English'},
        {value: 'Fr', title: 'French'},
      ],
      showName: true,
    },
  },
};

// Wrap your stories in the I18nextProvider component
const i18nextStoryDecorator = (Story, context) => {
  const { locale } = context.globals;

  i18next
    .use(HttpApi)
    .use(initReactI18next)
    .init({
      whitelist:['En','Fr'],
      lng: locale,
      fallbackLng: 'En',
      ns: 'index',
      defaultNS: 'index',
      defaultLocale: "En",
      debug: true,
    })
  // When the locale global changes
  // Set the new locale in i18n
  useEffect(() => {
    i18next.changeLanguage(locale);
  }, [locale]);

  return (
    // here catches the suspense from components not yet ready (still loading translations)
    // alternative set useSuspense false on i18next.options.react when initializing i18next
    <Suspense fallback={
loading translations...
}>
      <I18nextProvider i18n={i18next}>
        <Story />
      </I18nextProvider>
    </Suspense>
  );
};

// export decorators for storybook to wrap your stories in
export const decorators = [i18nextStoryDecorator];


问:
Is there any 3rd party service to give me the required fields that I need to make a international bank transfer by country code?
Is there any way to get the required fields/data for the user to provide to allow me to do a bank transfer to the user based on the country code?

For users from the USA, I would ask them to give me

country
city
address
company
identification
state
postcode

Is there any 3rd party service to give me the required fields that I need to make a international bank transfer by country code?


问:
Rails 3 Load Balancing of Mongrel Servers using Apache 2.2 on Windows Server 2008
I'm attempting to deploy a Rails 3 application onto a Windows Server 2008 server in production mode with Mongrel/Apache.

Here is my current setup:

Ruby 1.9.2

Rails 3.0.9

Mongrel 1.2.0.pre2

Windows Server 2008 (unfortunately this is a requirement)

Apache 2.2

I'm able to start my app in production mode on Mongrel, but it is not yet associated with Apache. My question is, can I set up Apache to do load balancing of multiple Mongrel servers running a Rails 3 app? Much of what I read made it sound next to impossible or very difficult due to incompatibility with the mongrel_service gem; is that still the case? Does anyone have this working?

Thank you!

ContentLicense: CC BY-SA 3.0


问:
Error on scalar variable declaration even when the variable is declared
I have this SQL statement; when executed in SSMS, it runs ok, but when executed through a scheduler, I get this error

Must declare the scalar variable "@student_id".

Can I get some help understanding what possibly could be causing this?

```<code>CREATE TABLE TABLE2
(
    TYPE1 nvarchar(256),
    TABLE_ID nvarchar(256)
);

DECLARE @student_id INT
SET @student_id = 1;

WHILE @student_id <= (SELECT COUNT(*) FROM STUDENT)
BEGIN
    DECLARE @area NVARCHAR(256)

    SET @area = (SELECT AREA
                 FROM
                     (SELECT
                          ROW_NUMBER() OVER(ORDER BY AREA ASC) AS NB_ROW,
                          AREA
                      FROM
                          STUDENT) AS TEMP
                 WHERE NB_ROW = @student_id)

    INSERT INTO TABLE2 (TYPE1, TABLE_ID)
        SELECT
            TYPE1, TABLE_ID
        FROM
            TABLE3

    SET @student_id = @student_id + 1
END;
</code>```

Body:
I have this SQL statement; when executed in SSMS, it runs ok, but when executed through a scheduler, I get this error

Must declare the scalar variable "@student_id".

Can I get some help understanding what possibly could be causing this?

CREATE TABLE TABLE2
(
    TYPE1 nvarchar(256),
    TABLE_ID nvarchar(256)
);

DECLARE @student_id INT
SET @student_id = 1;

WHILE @student_id <= (SELECT COUNT(*) FROM STUDENT)
BEGIN
    DECLARE @area NVARCHAR(256)

    SET @area = (SELECT AREA
                 FROM
                     (SELECT
                          ROW_NUMBER() OVER(ORDER BY AREA ASC) AS NB_ROW,
                          AREA
                      FROM
                          STUDENT) AS TEMP
                 WHERE NB_ROW = @student_id)

    INSERT INTO TABLE2 (TYPE1, TABLE_ID)
        SELECT
            TYPE1, TABLE_ID
        FROM
            TABLE3

    SET @student_id = @student_id + 1
END;


问:
Vega not producing output in VS Code Jupyter notebook
I am a noob in Vega and Jupyter. I'm trying to get the environment set up and I've done something wrong.

I'm able to load a dataframe and import Vega or VegaLite.

```<code>import pandas as pd
df = pd.read_json('https://vega.github.io/vega-lite/data/cars.json')
df.head()
from vega import VegaLite
</code>```

But when I try to create a chart I get no output or errors:

```<code>VegaLite({
  "mark": "point",
  "encoding": {
    "y": {"type": "quantitative", "field": "Acceleration"},
    "x": {"type": "quantitative", "field": "Horsepower"}
  }
}, df)
</code>```

Occasionally I have gotten this:

```<code>c:\Users\me\AppData\Local\Programs\Python\Python38\lib\site-packages\vega\utils.py:51: FutureWarning: iteritems is deprecated and will be removed in a future version. Use .items instead. for col_name, dtype in df.dtypes.iteritems():
</code>```

Any ideas?

Body:
I am a noob in Vega and Jupyter. I'm trying to get the environment set up and I've done something wrong.

I'm able to load a dataframe and import Vega or VegaLite.

import pandas as pd
df = pd.read_json('https://vega.github.io/vega-lite/data/cars.json')
df.head()
from vega import VegaLite

But when I try to create a chart I get no output or errors:

VegaLite({
  "mark": "point",
  "encoding": {
    "y": {"type": "quantitative", "field": "Acceleration"},
    "x": {"type": "quantitative", "field": "Horsepower"}
  }
}, df)

Occasionally I have gotten this:

c:\Users\me\AppData\Local\Programs\Python\Python38\lib\site-packages\vega\utils.py:51: FutureWarning: iteritems is deprecated and will be removed in a future version. Use .items instead. for col_name, dtype in df.dtypes.iteritems():

Any ideas?


问:
Firebase applyActionCode() returns INVALID_OOB_CODE
I'm trying to handle email verification in my react client.

So far I managed to send the verification email and the link redirects me to my client where I run applyActionCode(auth, oobCode) but I always get INVALID_OOB_CODE even though the email is marked as verified.

How do I tell if the oobCode is indeed invalid?


问:
getting user location in web view throws error cant get position of user
I am loading this form to web view but clicking location button logs out "error retrieving position" while in desktop chrome, it loads position and ask permissions correctly: https://ee.humanitarianresponse.info/x/mHDoR4g0

Here is part of the code that loads the web page:

```<code>@Destination
@Composable
fun LoadLink(

) {
    val remoteConfig = AppRemoteConfig()

    val link = "https://ee.humanitarianresponse.info/x/mHDoR4g0"
    var webView: WebView? = null
    AndroidView(factory = {
        WebView(it).apply {
            layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )

            settings.javaScriptEnabled = true
            settings.setSupportZoom(true)
            settings.domStorageEnabled = true
            settings.setGeolocationEnabled(true)
            settings.databaseEnabled = true

            webViewClient = object : WebViewClient() {

                override fun onPageStarted(view: WebView, url: String?, favicon: Bitmap?) {
                    backEnabled = view.canGoBack()
                }

                override fun onPageFinished(view: WebView?, url: String?) {
                    evaluateJavascriptWithFallback(view!!, injectFormProcessingScript(client))
                    super.onPageFinished(view, url)
                }

            }

            loadUrl(link)
            webView = this
        }
    }, update = {
        it.loadUrl(link)
    })
    BackHandler(enabled = backEnabled) {
        webView?.goBack()
    }
}

}

 }
</code>```

Body:
I am loading this form to web view but clicking location button logs out "error retrieving position" while in desktop chrome, it loads position and ask permissions correctly: https://ee.humanitarianresponse.info/x/mHDoR4g0

Here is part of the code that loads the web page:

@Destination
@Composable
fun LoadLink(

) {
    val remoteConfig = AppRemoteConfig()

    val link = "https://ee.humanitarianresponse.info/x/mHDoR4g0"
    var webView: WebView? = null
    AndroidView(factory = {
        WebView(it).apply {
            layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )

            settings.javaScriptEnabled = true
            settings.setSupportZoom(true)
            settings.domStorageEnabled = true
            settings.setGeolocationEnabled(true)
            settings.databaseEnabled = true

            webViewClient = object : WebViewClient() {

                override fun onPageStarted(view: WebView, url: String?, favicon: Bitmap?) {
                    backEnabled = view.canGoBack()
                }

                override fun onPageFinished(view: WebView?, url: String?) {
                    evaluateJavascriptWithFallback(view!!, injectFormProcessingScript(client))
                    super.onPageFinished(view, url)
                }

            }

            loadUrl(link)
            webView = this
        }
    }, update = {
        it.loadUrl(link)
    })
    BackHandler(enabled = backEnabled) {
        webView?.goBack()
    }
}

}

 }


问:
How to execute a method a set time after Alarm is triggered?
I am using Alarm Manager to trigger an alarm at a user picked time using TimePicker. I want to automatically execute a method 1 minute after this alarm. However I cannot figure out how to put the appropriate time in code.

```<code>listener = new TimePickerDialog.OnTimeSetListener() {
u/Override
public void onTimeSet(TimePicker timePicker, int i, int i1) {
c.set(Calendar.HOUR, i);
c.set(Calendar.MINUTE, i1);
start(c);

new Timer().schedule(new TimerTask() {
u/Override
public void run() {
//do something
}
}, timeDelay());`
</code>```

I've tried creating a time delay but its not correct, what's the right way to do this?

```<code>public long timeDelay(){
long timePlusDelay = c.getTimeInMillis() + 60000;
return timePlusDelay;
}
</code>```

I need the delay to be user picked time + 60 seconds. When I simply put a delay in seconds, it runs that amount of seconds after onTimeSet() is run but before the start(c) method. I'm a beginner so I'm probably missing something obvious, but I've tried different things to no avail. Any help would be greatly appreciated.

I tried setting the delay to 60000 milliseconds, but it executes 60000ms after onTimeSet is called. I need it to execute 60000ms after start(c) is called.

Body:
I am using Alarm Manager to trigger an alarm at a user picked time using TimePicker. I want to automatically execute a method 1 minute after this alarm. However I cannot figure out how to put the appropriate time in code.

listener = new TimePickerDialog.OnTimeSetListener() {
u/Override
public void onTimeSet(TimePicker timePicker, int i, int i1) {
c.set(Calendar.HOUR, i);
c.set(Calendar.MINUTE, i1);
start(c);

new Timer().schedule(new TimerTask() {
u/Override
public void run() {
//do something
}
}, timeDelay());`

I've tried creating a time delay but its not correct, what's the right way to do this?

public long timeDelay(){
long timePlusDelay = c.getTimeInMillis() + 60000;
return timePlusDelay;
}

I need the delay to be user picked time + 60 seconds. When I simply put a delay in seconds, it runs that amount of seconds after onTimeSet() is run but before the start(c) method. I'm a beginner so I'm probably missing something obvious, but I've tried different things to no avail. Any help would be greatly appreciated.

I tried setting the delay to 60000 milliseconds, but it executes 60000ms after onTimeSet is called. I need it to execute 60000ms after start(c) is called.


问:
ValueError: Input 0 of layer "sequential" is incompatible with the layer: expected shape=(None, 1, 1), found shape=(None, 4)
Here is the little project of commodity price detection, and it has already has the dataset and colab code, but I get an error when I execute the code below

```<code> look_back = 1
        X_train, Y_train = create_dataset(self.X, look_back)
        X_test, Y_test = create_dataset(self.Y, look_back)

        # reshape input to be [samples, time steps, features]
        X_train = np.reshape(X_train, (X_train.shape[0], 1, X_train.shape[1]))
        X_test = np.reshape(X_test, (X_test.shape[0], 1, X_test.shape[1]))
        print(X_train)

        # create and fit the LSTM network
        self.model = Sequential()
        self.model.add(LSTM(4, input_shape=(1, look_back)))
        self.model.add(Dense(1))
        self.model.add(tf.keras.layers.Dense(256, input_shape=(X_train.shape[1],),                      activation='sigmoid'))
        self.model.compile(loss='mean_squared_error', optimizer='adam')
        self.model.fit(X_train, Y_train, epochs=10, batch_size=1, verbose=2)
</code>```

Body:
Here is the little project of commodity price detection, and it has already has the dataset and colab code, but I get an error when I execute the code below

 look_back = 1
        X_train, Y_train = create_dataset(self.X, look_back)
        X_test, Y_test = create_dataset(self.Y, look_back)

        # reshape input to be [samples, time steps, features]
        X_train = np.reshape(X_train, (X_train.shape[0], 1, X_train.shape[1]))
        X_test = np.reshape(X_test, (X_test.shape[0], 1, X_test.shape[1]))
        print(X_train)

        # create and fit the LSTM network
        self.model = Sequential()
        self.model.add(LSTM(4, input_shape=(1, look_back)))
        self.model.add(Dense(1))
        self.model.add(tf.keras.layers.Dense(256, input_shape=(X_train.shape[1],),                      activation='sigmoid'))
        self.model.compile(loss='mean_squared_error', optimizer='adam')
        self.model.fit(X_train, Y_train, epochs=10, batch_size=1, verbose=2)


问:
creation of a R dataframe from another df and assigment to each element the column title name
I would like to change the structure of my dataframe in R. I would have something like this:

```<code>df <- data.frame(Letter = c("a", "b", "c", "d", "e"),
                 Number = c(23, 41, 32, 58, 26)
)
print (df)
</code>```
```<code>  Letter Number
1      a     23
2      b     41
3      c     32
4      d     58
5      e     26
</code>```

I want to append each column content below each other, and then rename the corresponding column with the originating column name. The output would be the following:

Could you please help me?

I would expect the output to be something like this.

```<code>   A      B
1  a Letter
2  b Letter
3  c Letter
4  d Letter
5 23 Number
6 41 Number
7 32 Number
8 58 Number
</code>```

Body:
I would like to change the structure of my dataframe in R. I would have something like this:

df <- data.frame(Letter = c("a", "b", "c", "d", "e"),
                 Number = c(23, 41, 32, 58, 26)
)
print (df)

  Letter Number
1      a     23
2      b     41
3      c     32
4      d     58
5      e     26

I want to append each column content below each other, and then rename the corresponding column with the originating column name. The output would be the following:

Could you please help me?

I would expect the output to be something like this.

   A      B
1  a Letter
2  b Letter
3  c Letter
4  d Letter
5 23 Number
6 41 Number
7 32 Number
8 58 Number


问:
can not ran API, which uses PostgreSQL
I have Installed and Deleted pgAdmin several times and several versions, as I can not start the API. So, it does not work, even if followed all instructions and created a database with the correct name on my mac. Then, I installed PostgreSQL (14) with homebrew. However, in pgadmin it does not show PostgreSQL 14 as a database, and the command  postgres -V shows only this postgres (PostgreSQL) 14.6 (Homebrew). But I have these two versions of DB. When running the API, it shows an error incorrect error: password authentication failed for user "Postgres"
every time when downloading the DB I did the password as 12345. What should I do now?

I tried to delete it entirely on the terminal and in an applications folder.
here's pgAdmin

Title: can not ran API, which uses PostgreSQL


问:
Infinite loop from JWT expiring
Hi I'm using this tutorial https://github.com/bradtraversy/mern-tutorial

I guess it must have slipped past him, but after 7 days when the JWT expires, the website goes into an infinite loop telling me I'm not authorized. I set the JWT expiration to 10 seconds to test the app, and I can't find a solution. I'm thinking he never routes it to logout if the token expires, but I'm new to MERN and can't figure out where to put that.

Title: Infinite loop from JWT expiring


问:
Choose camera on mobile web browser
i'm trying to implement a barcode reader on my angular app.
It's everything going great, but, when I try it on devices with more cameras it's getting the Ultrawide cam. How can I choose the main camera?

I'm using zxing scanner and this is my component

```<code>
  <zxing-scanner
  #scanner
  start="true"
  [torch]="true"
  [enable]="true"
  [tryHarder]="true"
  [autofocusEnabled]="true"
  [formats]="formatsAvailable"
  [device]="selectedDevice"
  (scanSuccess)="handleCodeResult($event)">
  </zxing-scanner>

</code>```

Title: Choose camera on mobile web browser

Body:
i'm trying to implement a barcode reader on my angular app.
It's everything going great, but, when I try it on devices with more cameras it's getting the Ultrawide cam. How can I choose the main camera?

I'm using zxing scanner and this is my component

  <zxing-scanner
  #scanner
  start="true"
  [torch]="true"
  [enable]="true"
  [tryHarder]="true"
  [autofocusEnabled]="true"
  [formats]="formatsAvailable"
  [device]="selectedDevice"
  (scanSuccess)="handleCodeResult($event)">
  </zxing-scanner>