问:
Flutter app doesn't play custom notification sound when it's executed inside iOS
I'm working in a project which receives notification using Firebase Cloud Messaging and plays custom sounds when the payload reach the app.It works perfectly while running on Android, but on iOS it only plays the pattern sound of iOS, never plays the custom sound. I already put the audios inside Resource folder, try copying the audio files to the ios folder but even this way, the app never find the .wav files or maybe for some reason it only plays the pattern sound. Here some excerpt of my notification.service.dart class:

```<code>class NotificationService
  late FlutterLocalNotificationsPlugin plugin;
  late AndroidNotificationDetails androidDetails;
  ```

NotificationService() {
    plugin = FlutterLocalNotificationsPlugin();
    _setupNotification();
  }

  _setupNotification() async {
    print('_setupNotification');
    await _setupTimeZone();
    await _initialize();
  }

  _setupTimeZone() async {
    print('_setupTimeZone');
    tz.initializeTimeZones();
    final String? timeZoneName = await FlutterNativeTimezone.getLocalTimezone();
    tz.setLocalLocation(tz.getLocation(timeZoneName!));
  }

  _initialize() async {
    print('notification _initialize');

    void _requestPermissions(){
      plugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()
      ?._requestPermissions(
        alert: true,
        badge: true,
        sound: true,
      );
    }

    const ios = IOSInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: true,
    )

    const android = AndroidInitializationSettings('@mipmap/ic_launcher');
    await plugin.initialize(
      const InitializationSettings(
        android: android,
        iOS: ios,
      ),
      onSelectNotification: _onSelectNotification,
    );
  }

  _onSelectNotification(String? payload) {
    print('_onSelectNotification');
    if (payload != null && payload.isNotEmpty) {
      var array = payload.split('/');
      if (array.length == 2) {
        var acao = int.tryParse(array[0]);
        var idDispositivo = array[1].toString();
        if (acao != null && idDispositivo.isNotEmpty) {
          int disIndex = serverConnection.equipamentos
              .indexWhere((x) => x.serverId == idDispositivo);
          if (disIndex != -1) {
            DispositivoModel dis = serverConnection.equipamentos[disIndex];
            if (dis.sep != null) {
              sepService.showDialogAlertaAcionado(dis);
            } else if (dis.gate != null) {
              gateService.showGateStatus(
                  Routes.navigatorKey!.currentContext!, dis);
            }
          }
        }
      }

      Navigator.of(Routes.navigatorKey!.currentContext!)
          .pushReplacementNamed(payload);
    }
  }

  showNotification(RemoteMessage message) async {
    print('showNotification');

    var user = await accountService.getUser();
    print('isLoggedIn ${accountService.isLoggedIn}');
    print('isLoggedIn ${user}');
    if (accountService.isLoggedIn == true && user != null) {
        _conteudoNotificacao(message);

    }
  }

  _conteudoNotificacao(RemoteMessage message) {
    RemoteMessageData data = RemoteMessageData.fromJson(message.data);
    sound = data.sound != 'default' && data.sound != null
        ? data.sound ?? 'gate'
        : 'gate';

    print('sound $sound');
    AndroidNotificationChannel channel = AndroidNotificationChannel(
      'Adviser $sound',
      'AdviserChannel',
      description: '',
      importance: Importance.high,
      sound: RawResourceAndroidNotificationSound(sound),
      enableVibration: true,
      enableLights: true,
    );

    plugin = FlutterLocalNotificationsPlugin();
    String title = 'SouHi';
    if (data.route != null) {
      var array = data.route!.split('/');
      if (array.length == 2) {
        var acao = int.tryParse(array[0]);
        var idDispositivo = array[1].toString();
        if (acao != null && idDispositivo.isNotEmpty) {
          int disIndex = serverConnection.equipamentos
              .indexWhere((x) => x.serverId == idDispositivo);
          if (disIndex != -1) {
            DispositivoModel dis = serverConnection.equipamentos[disIndex];
            if (dis.sep != null) {
              title = 'SEP';
            } else if (dis.gate != null) {
              title = 'Portão';
            }
          }
        }
      }
    }

    plugin.show(
      message.hashCode,
      title,
      data.body,
      NotificationDetails(
        android: AndroidNotificationDetails(
          channel.id,
          channel.name,
          channelDescription: channel.description,
          importance: channel.importance,
          priority: Priority.high,
          showProgress: true,
          enableLights: true,
          enableVibration: true,
          visibility: NotificationVisibility.public,
          sound: RawResourceAndroidNotificationSound(sound),
        ),
        iOS: IOSNotificationDetails(
          presentSound: true,
          presentBadge: true,
          presentAlert: true,
          sound: sound,
        ),
      ),
      payload: data.route,
    );
  }

  checkForNotifications() async {
    print('checkForNotifications');
    final details = await plugin.getNotificationAppLaunchDetails();
    if (details != null && details.didNotificationLaunchApp) {
      _onSelectNotification(details.payload);
    }
  }

  stopNotification(int? id) async {
    print('stopNotification');
    if (id != null) {
      await plugin.cancel(id);
    } else {
      await plugin.cancelAll();
    }
  }
}
```
```

```

Body:
I'm working in a project which receives notification using Firebase Cloud Messaging and plays custom sounds when the payload reach the app.It works perfectly while running on Android, but on iOS it only plays the pattern sound of iOS, never plays the custom sound. I already put the audios inside Resource folder, try copying the audio files to the ios folder but even this way, the app never find the .wav files or maybe for some reason it only plays the pattern sound. Here some excerpt of my notification.service.dart class:

class NotificationService
  late FlutterLocalNotificationsPlugin plugin;
  late AndroidNotificationDetails androidDetails;
  ```

NotificationService() {
    plugin = FlutterLocalNotificationsPlugin();
    _setupNotification();
  }

  _setupNotification() async {
    print('_setupNotification');
    await _setupTimeZone();
    await _initialize();
  }

  _setupTimeZone() async {
    print('_setupTimeZone');
    tz.initializeTimeZones();
    final String? timeZoneName = await FlutterNativeTimezone.getLocalTimezone();
    tz.setLocalLocation(tz.getLocation(timeZoneName!));
  }

  _initialize() async {
    print('notification _initialize');

    void _requestPermissions(){
      plugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()
      ?._requestPermissions(
        alert: true,
        badge: true,
        sound: true,
      );
    }

    const ios = IOSInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: true,
    )

    const android = AndroidInitializationSettings('@mipmap/ic_launcher');
    await plugin.initialize(
      const InitializationSettings(
        android: android,
        iOS: ios,
      ),
      onSelectNotification: _onSelectNotification,
    );
  }

  _onSelectNotification(String? payload) {
    print('_onSelectNotification');
    if (payload != null && payload.isNotEmpty) {
      var array = payload.split('/');
      if (array.length == 2) {
        var acao = int.tryParse(array[0]);
        var idDispositivo = array[1].toString();
        if (acao != null && idDispositivo.isNotEmpty) {
          int disIndex = serverConnection.equipamentos
              .indexWhere((x) => x.serverId == idDispositivo);
          if (disIndex != -1) {
            DispositivoModel dis = serverConnection.equipamentos[disIndex];
            if (dis.sep != null) {
              sepService.showDialogAlertaAcionado(dis);
            } else if (dis.gate != null) {
              gateService.showGateStatus(
                  Routes.navigatorKey!.currentContext!, dis);
            }
          }
        }
      }

      Navigator.of(Routes.navigatorKey!.currentContext!)
          .pushReplacementNamed(payload);
    }
  }

  showNotification(RemoteMessage message) async {
    print('showNotification');

    var user = await accountService.getUser();
    print('isLoggedIn ${accountService.isLoggedIn}');
    print('isLoggedIn ${user}');
    if (accountService.isLoggedIn == true && user != null) {
        _conteudoNotificacao(message);

    }
  }

  _conteudoNotificacao(RemoteMessage message) {
    RemoteMessageData data = RemoteMessageData.fromJson(message.data);
    sound = data.sound != 'default' && data.sound != null
        ? data.sound ?? 'gate'
        : 'gate';

    print('sound $sound');
    AndroidNotificationChannel channel = AndroidNotificationChannel(
      'Adviser $sound',
      'AdviserChannel',
      description: '',
      importance: Importance.high,
      sound: RawResourceAndroidNotificationSound(sound),
      enableVibration: true,
      enableLights: true,
    );

    plugin = FlutterLocalNotificationsPlugin();
    String title = 'SouHi';
    if (data.route != null) {
      var array = data.route!.split('/');
      if (array.length == 2) {
        var acao = int.tryParse(array[0]);
        var idDispositivo = array[1].toString();
        if (acao != null && idDispositivo.isNotEmpty) {
          int disIndex = serverConnection.equipamentos
              .indexWhere((x) => x.serverId == idDispositivo);
          if (disIndex != -1) {
            DispositivoModel dis = serverConnection.equipamentos[disIndex];
            if (dis.sep != null) {
              title = 'SEP';
            } else if (dis.gate != null) {
              title = 'Portão';
            }
          }
        }
      }
    }

    plugin.show(
      message.hashCode,
      title,
      data.body,
      NotificationDetails(
        android: AndroidNotificationDetails(
          channel.id,
          channel.name,
          channelDescription: channel.description,
          importance: channel.importance,
          priority: Priority.high,
          showProgress: true,
          enableLights: true,
          enableVibration: true,
          visibility: NotificationVisibility.public,
          sound: RawResourceAndroidNotificationSound(sound),
        ),
        iOS: IOSNotificationDetails(
          presentSound: true,
          presentBadge: true,
          presentAlert: true,
          sound: sound,
        ),
      ),
      payload: data.route,
    );
  }

  checkForNotifications() async {
    print('checkForNotifications');
    final details = await plugin.getNotificationAppLaunchDetails();
    if (details != null && details.didNotificationLaunchApp) {
      _onSelectNotification(details.payload);
    }
  }

  stopNotification(int? id) async {
    print('stopNotification');
    if (id != null) {
      await plugin.cancel(id);
    } else {
      await plugin.cancelAll();
    }
  }
}


来源: stackexchange

问:
Tools to send automated emails with dynamic content
I would like to send automated emails to a group of users present in my DB. The emails would contain data with dynamic content. Mostly a table with different set of items. I was looking to use mailchimp templates for that, but it doesn't seem to allow for the kind of dynamic content I am looking for. Essentially for each user, my code would come up with a json array of items to populate the table with.
I am at a loss as to where to get started there. Any interesting tools to do this kind of work, that can be called programmatically from python?</p>

ContentLicense: CC BY-SA 4.0


问:
How to: React Native Android App as Http Serve. P2P Communication
I'm brainstorming about a project where I would have an Android device serving a HTTP server to handle requests from a second device. So basically a P2P communication between two devices.

I thought about something like this -- The Android device’s hotspot could be turned on, allowing the second device to connect to it’s network. That’s when the React Native app would open a server, allowing the second device to send HTTP requests.

I’ve made some research on libraries but couldn’t find anything suitable. There are some libraries that open local servers but what I’m trying to do is a P2P communication between two devices.

Could you help me with some advice?


问:
Is there a way to reduce/optimize multiple .copyValuesToRange statements?
I'm trying to optimize my script. Part of the script has multiple .copyValuesToRange statements. Is there a way to optimize the following?

```<code>
    const SS = SpreadsheetApp.getActive();
    let source = SS.getSheetByName("Update List");
    let destination = SS.getSheetByName("Power Level");

    source.getRange('TIER1Master').copyValuesToRange(destination, 12, 12, 6, 29);
    source.getRange('TIER2Master').copyValuesToRange(destination, 15, 15, 6, 13);
    source.getRange('TIER3Master').copyValuesToRange(destination, 15, 15, 16, 23);
    source.getRange('PINNACLE1Master').copyValuesToRange(destination, 18, 18, 6, 23);
    source.getRange('PINNACLE2Master').copyValuesToRange(destination, 21, 21, 6, 29);
    source.getRange('MasterListTimestamp').copyValuesToRange(destination, 15, 15, 1, 1);

</code>```

I've used .getRangeList in other areas of my script that were given the same value but I don't know if that can be applied here since the values are different and from different sized ranges.

I'm new to learning Apps Script, javascript & coding in general. Any help is greatly appreciated.

Thank you.

Body:
I'm trying to optimize my script. Part of the script has multiple .copyValuesToRange statements. Is there a way to optimize the following?

    const SS = SpreadsheetApp.getActive();
    let source = SS.getSheetByName("Update List");
    let destination = SS.getSheetByName("Power Level");

    source.getRange('TIER1Master').copyValuesToRange(destination, 12, 12, 6, 29);
    source.getRange('TIER2Master').copyValuesToRange(destination, 15, 15, 6, 13);
    source.getRange('TIER3Master').copyValuesToRange(destination, 15, 15, 16, 23);
    source.getRange('PINNACLE1Master').copyValuesToRange(destination, 18, 18, 6, 23);
    source.getRange('PINNACLE2Master').copyValuesToRange(destination, 21, 21, 6, 29);
    source.getRange('MasterListTimestamp').copyValuesToRange(destination, 15, 15, 1, 1);

I've used .getRangeList in other areas of my script that were given the same value but I don't know if that can be applied here since the values are different and from different sized ranges.

I'm new to learning Apps Script, javascript & coding in general. Any help is greatly appreciated.

Thank you.


问:
how to search emailid registered or not and add in friends table?
below is my code of Getx Flutter

```<code>void onSearch() async {
  FirebaseFirestore _firestore = FirebaseFirestore.instance;

  await _firestore
      .collection('user')
      .where("Email", isEqualTo: _search.text)
      .get()
      .then((value) {

      userMap = value.docs[0].data();

    });
    print(userMap);
  });
}
</code>```

searching for solution of search bar where user can find result email id is in my friend list or not.

Body:
below is my code of Getx Flutter

void onSearch() async {
  FirebaseFirestore _firestore = FirebaseFirestore.instance;

  await _firestore
      .collection('user')
      .where("Email", isEqualTo: _search.text)
      .get()
      .then((value) {

      userMap = value.docs[0].data();

    });
    print(userMap);
  });
}

searching for solution of search bar where user can find result email id is in my friend list or not.


问:
Can't make the Sidebar close in fields other than its field (clickOutside)?
Made a listener that will listen to clicks in the radius is not his and should close the sidebar but for some reason it either does not close or just does not open (if does not open, I think there is a double click, ie open and close at once)

sidebar.component.ts - child component

```<code>export class SidebarComponent implements OnInit {

  constructor(private elementRef: ElementRef) { }

  @Input() sideNavStatus: boolean = false;
  @Output() public clickOutside = new EventEmitter<MouseEvent>();

     @HostListener('document: click', ['$event', '$event.target'])
     public onClick(event: MouseEvent, targetElement: HTMLElement) : void {
       if(!targetElement) {
         return;
       }
       const clickedInside = this.elementRef.nativeElement.contains(targetElement);
       if(!clickedInside) {
         this.clickOutside.emit(event);
       }
     }
     ngOnInit(): void { }
}
</code>```

sidebar.component.html

```<code><div class="side-nav-content">
    <ul class="nav-list" [ngClass]="{'nav-list-open': sideNavStatus}">
        <li class="nav-list-item" *ngFor="let item of list">
            <i class="{{item.icon}}"></i>
            <span>
                <a class="sidenav-nav-link" [routerLink]="item.routerLink">{{item.name}}</a>
            </span>
    </ul>
</div>
</code>```

mainpage.component.ts Parent component

```<code>export class MainpageComponent implements OnInit {

 sideNavStatus: boolean = false;

  constructor() { }

  ngOnInit(): void {
  }

  closeSidebar() {
      this.sideNavStatus = false
  }

}
</code>```

mainpage.component.html

```<code><div class="container-fluid g-0 sidebar-container">
    <main>

    <app-header
            (sideNavToggled)="sideNavStatus = $event;">
    </app-header>

        <app-sidebar [sideNavStatus]="sideNavStatus"
                     (clickOutside)="closeSidebar()"
                     [ngClass]="{'app-side-nav-open': sideNavStatus}">
        </app-sidebar>

        <div class="display-area p-3" [ngClass]="{'display-area-shrink': sideNavStatus}">

            <div class="container">
                <router-outlet></router-outlet>
            </div>
        </div>
    <app-footer></app-footer>
    </main>
</div>
</code>```
```<code>if(!clickedInside) {
   console.log('click')
   this.clickOutside.emit(event);
}
</code>```

Here and tried to output to the console, really when you click in another area triggers a click, and output to the console clickedInside - shows false
I will be very grateful for help.

Body:
Made a listener that will listen to clicks in the radius is not his and should close the sidebar but for some reason it either does not close or just does not open (if does not open, I think there is a double click, ie open and close at once)

sidebar.component.ts - child component

export class SidebarComponent implements OnInit {

  constructor(private elementRef: ElementRef) { }

  @Input() sideNavStatus: boolean = false;
  @Output() public clickOutside = new EventEmitter<MouseEvent>();

     @HostListener('document: click', ['$event', '$event.target'])
     public onClick(event: MouseEvent, targetElement: HTMLElement) : void {
       if(!targetElement) {
         return;
       }
       const clickedInside = this.elementRef.nativeElement.contains(targetElement);
       if(!clickedInside) {
         this.clickOutside.emit(event);
       }
     }
     ngOnInit(): void { }
}

sidebar.component.html

                {{item.name}}

mainpage.component.ts Parent component

export class MainpageComponent implements OnInit {

 sideNavStatus: boolean = false;

  constructor() { }

  ngOnInit(): void {
  }

  closeSidebar() {
      this.sideNavStatus = false
  }

}

mainpage.component.html

    <app-header
            (sideNavToggled)="sideNavStatus = $event;">
    </app-header>

        <app-sidebar [sideNavStatus]="sideNavStatus"
                     (clickOutside)="closeSidebar()"
                     [ngClass]="{'app-side-nav-open': sideNavStatus}">
        </app-sidebar>

                <router-outlet></router-outlet>

    <app-footer></app-footer>

if(!clickedInside) {
   console.log('click')
   this.clickOutside.emit(event);
}

Here and tried to output to the console, really when you click in another area triggers a click, and output to the console clickedInside - shows false
I will be very grateful for help.


问:
Getting a gif to show up on a blob
When users make selections for the first two inputs and click the download button, I want it to that them to a blob link that has the gif there. However, currently, when the users make selections and click the download button, it is properly taking them to a blob link but the gif is not showing up on it. The gif is trying to show up on the main link that the button is on and I am not sure how to fix it.

document.getElementById('button_fg').addEventListener('click', function() {
  // show the box if it's hidden, or hide it if it's visible
  document.getElementById('box_fg').style.display =
    document.getElementById('box_fg').style.display === 'none' ? 'block' : 'none';
});

// close the box when the user clicks outside of it
document.addEventListener('click', function(event) {
  // check if the clicked element is the button or is inside the open box
  var isButton = event.target.closest('#button_fg') !== null;
  var isInsideBox = event.target.closest('#box_fg') !== null;

  // if the clicked element is not the button or inside the box, hide the box
  if (!isButton && !isInsideBox) {
    document.getElementById('box_fg').style.display = 'none';
  }
});
// declare the selectedValue variable
var selectedValue1;
var dropdown_fg = document.getElementById('dropdown_fg');

// add an event listener for the 'change' event on the dropdown menu
dropdown_fg.addEventListener('change', function() {
  // get the selected option
  var selectedOption1 = this.options[this.selectedIndex].value;

  // save the selected option as a variable
  selectedValue1 = parseInt(selectedOption1);
});

var selectedValue2;
var dropdown_fg2 = document.getElementById('dropdown_fg2');

// add an event listener for the 'change' event on the dropdown menu
dropdown_fg2.addEventListener('change', function() {
  // get the selected option
  var selectedOption2 = this.options[this.selectedIndex].value;

  // save the selected option as a variable
  selectedValue2 = parseInt(selectedOption2);
  // check if the selected option is the top option

});
// create a string that points to the directory
var directory = '#';
// add an event listener for the 'change' event on the dropdown menu
dropdown_fg2.addEventListener('change', function() {

  // check if the selectedValue1 and selectedValue2 variables have been assigned values
  if (!isNaN(selectedValue1) && !isNaN(selectedValue2)) {

    // create an array of images
    var images = [];

    // set the starting image
    var startImage = selectedValue1;

    // set the ending image
    var endImage = selectedValue2;

    // set the step size for the images
    var step = 6;

    // create a loop to add the images to the array
    for (var i = startImage; i <= endImage; i += step) {
      var filePath = directory + "gfs_6hr_2m_temp_hour_" + i + '.png';
      // add the image to the array
      images.push(filePath);
    }
    const downloadButton = document.getElementById('download-button2');

    // Handle the button click
    downloadButton.addEventListener('click', function() {
      /// Generate gif
      gifshot.createGIF({
        'images': images,
        'gifWidth': 1144,
        'gifHeight': 894,
        'interval': 0.33
      }, function(obj) {
        if (!obj.error) {
          var image = obj.image;

          // Extract the GIF data from the base64-encoded string
          var gifDataString = image.split(',')[1];
          var gifData = new Uint8Array(atob(gifDataString));

          // Create a Blob object that represents the GIF file
          var gifBlob = new Blob([gifData], {
            type: 'image/gif'
          });

          // Use the URL.createObjectURL() method to create a URL for the Blob
          var gifUrl = URL.createObjectURL(gifBlob);

          // You can then use the URL to open the GIF file in a new window or to display it on your website

          animatedImage = document.createElement('img');
          animatedImage.src = gifUrl;
          document.body.appendChild(animatedImage);
          window.open(gifUrl);
        }
      });
    });

  }
})```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#box_fg {
  position: absolute;
  display: none;
  background-color: #f1f1f1;
  padding: 20px;
  /* hide the box by default */
  max-width: 15%;
  /* set a maximum width for the box */
  overflow: hidden;
  /* hide any content that overflows the box */
  border: 1px solid black;
  left: 55.3%;
  top: 70.5%;
}

#button_fg {
  position: absolute;
  /* create a positioning context for the list items */
  background-color: #333;
  color: white;
  text-decoration: none;
  width: 10%;
  text-align: center;
  transition: background-color 0.2s;
  display: inline-block;
  cursor: pointer;
  font-family: Arial, Helvetica, sans-serif;
  border-radius: 10px;
  left: 55.3%;
  top: 84.8%;
}

#button_fg:hover {
  cursor: pointer;
  background-color: #525252;
  transition: background-color 0.2s;
}

#download-button2:hover {
  cursor: pointer;
}

/* 12/13/14 */

@media only screen and (max-width: 600px) {
  #button_fg {
    position: absolute;
    /* create a positioning context for the list items */
    width: 23%;
    left: 26vw;
    top: 105vw;
    font-size: 12px;
    height: 7vw;
  }
  #box_fg {
    position: absolute;
    left: 26vw;
    top: 78vw;
    z-index: 999;
    max-width: 50%;
  }
}

@media (min-width: 800px) {
  #button_fg {
    top: 39vw;
    font-size: 14px;
  }
  #box_fg {
    top: 32vw;
    font-size: 14px;
  }
}

@media (min-width: 1050px) {
  #box_fg {
    font-size: 16px;
  }
  #button_fg {
    font-size: 16px;
  }
}

@media (min-width: 1500px) {
  #button_fg {
    font-size: 18px;
  }
  #box_fg {
    font-size: 18px;
  }
}

@media (min-width: 2000px) {
  #button_fg {
    font-size: 24px;
  }
  #box_fg {
    font-size: 24px;
  }
}</code>```

<button id="button_fg">Forecast Gif</button>

  Starting Hour:
  <select id="dropdown_fg">
    <option id="dropdown_fg" value="">Select Hour</option>
    <option value="0">0</option>
    <option value="6">6</option>
    <option value="12">12</option>
    <option value="18">18</option>
    <option value="24">24</option>
    <option value="30">30</option>
    <option value="36">36</option>
    <option value="42">42</option>

  </select>

    Ending Hour:
    <select id="dropdown_fg2">
      <option id="dropdown_fg2" value="">Select Hour</option>
      <option value="6">6</option>
      <option value="12">12</option>
      <option value="18">18</option>
      <option value="24">24</option>
      <option value="30">30</option>
      <option value="36">36</option>
      <option value="42">42</option>
      <option value="48">48</option>

    </select>

    <button id="download-button2">Download GIF</button>

```

Title: Getting a gif to show up on a blob

Body:
When users make selections for the first two inputs and click the download button, I want it to that them to a blob link that has the gif there. However, currently, when the users make selections and click the download button, it is properly taking them to a blob link but the gif is not showing up on it. The gif is trying to show up on the main link that the button is on and I am not sure how to fix it.

document.getElementById('button_fg').addEventListener('click', function() {
  // show the box if it's hidden, or hide it if it's visible
  document.getElementById('box_fg').style.display =
    document.getElementById('box_fg').style.display === 'none' ? 'block' : 'none';
});

// close the box when the user clicks outside of it
document.addEventListener('click', function(event) {
  // check if the clicked element is the button or is inside the open box
  var isButton = event.target.closest('#button_fg') !== null;
  var isInsideBox = event.target.closest('#box_fg') !== null;

  // if the clicked element is not the button or inside the box, hide the box
  if (!isButton && !isInsideBox) {
    document.getElementById('box_fg').style.display = 'none';
  }
});
// declare the selectedValue variable
var selectedValue1;
var dropdown_fg = document.getElementById('dropdown_fg');

// add an event listener for the 'change' event on the dropdown menu
dropdown_fg.addEventListener('change', function() {
  // get the selected option
  var selectedOption1 = this.options[this.selectedIndex].value;

  // save the selected option as a variable
  selectedValue1 = parseInt(selectedOption1);
});

var selectedValue2;
var dropdown_fg2 = document.getElementById('dropdown_fg2');

// add an event listener for the 'change' event on the dropdown menu
dropdown_fg2.addEventListener('change', function() {
  // get the selected option
  var selectedOption2 = this.options[this.selectedIndex].value;

  // save the selected option as a variable
  selectedValue2 = parseInt(selectedOption2);
  // check if the selected option is the top option

});
// create a string that points to the directory
var directory = '#';
// add an event listener for the 'change' event on the dropdown menu
dropdown_fg2.addEventListener('change', function() {

  // check if the selectedValue1 and selectedValue2 variables have been assigned values
  if (!isNaN(selectedValue1) && !isNaN(selectedValue2)) {

    // create an array of images
    var images = [];

    // set the starting image
    var startImage = selectedValue1;

    // set the ending image
    var endImage = selectedValue2;

    // set the step size for the images
    var step = 6;

    // create a loop to add the images to the array
    for (var i = startImage; i <= endImage; i += step) {
      var filePath = directory + "gfs_6hr_2m_temp_hour_" + i + '.png';
      // add the image to the array
      images.push(filePath);
    }
    const downloadButton = document.getElementById('download-button2');

    // Handle the button click
    downloadButton.addEventListener('click', function() {
      /// Generate gif
      gifshot.createGIF({
        'images': images,
        'gifWidth': 1144,
        'gifHeight': 894,
        'interval': 0.33
      }, function(obj) {
        if (!obj.error) {
          var image = obj.image;

          // Extract the GIF data from the base64-encoded string
          var gifDataString = image.split(',')[1];
          var gifData = new Uint8Array(atob(gifDataString));

          // Create a Blob object that represents the GIF file
          var gifBlob = new Blob([gifData], {
            type: 'image/gif'
          });

          // Use the URL.createObjectURL() method to create a URL for the Blob
          var gifUrl = URL.createObjectURL(gifBlob);

          // You can then use the URL to open the GIF file in a new window or to display it on your website

          animatedImage = document.createElement('img');
          animatedImage.src = gifUrl;
          document.body.appendChild(animatedImage);
          window.open(gifUrl);
        }
      });
    });

  }
})

#box_fg {
  position: absolute;
  display: none;
  background-color: #f1f1f1;
  padding: 20px;
  /* hide the box by default */
  max-width: 15%;
  /* set a maximum width for the box */
  overflow: hidden;
  /* hide any content that overflows the box */
  border: 1px solid black;
  left: 55.3%;
  top: 70.5%;
}

#button_fg {
  position: absolute;
  /* create a positioning context for the list items */
  background-color: #333;
  color: white;
  text-decoration: none;
  width: 10%;
  text-align: center;
  transition: background-color 0.2s;
  display: inline-block;
  cursor: pointer;
  font-family: Arial, Helvetica, sans-serif;
  border-radius: 10px;
  left: 55.3%;
  top: 84.8%;
}

#button_fg:hover {
  cursor: pointer;
  background-color: #525252;
  transition: background-color 0.2s;
}

#download-button2:hover {
  cursor: pointer;
}

/* 12/13/14 */

@media only screen and (max-width: 600px) {
  #button_fg {
    position: absolute;
    /* create a positioning context for the list items */
    width: 23%;
    left: 26vw;
    top: 105vw;
    font-size: 12px;
    height: 7vw;
  }
  #box_fg {
    position: absolute;
    left: 26vw;
    top: 78vw;
    z-index: 999;
    max-width: 50%;
  }
}

@media (min-width: 800px) {
  #button_fg {
    top: 39vw;
    font-size: 14px;
  }
  #box_fg {
    top: 32vw;
    font-size: 14px;
  }
}

@media (min-width: 1050px) {
  #box_fg {
    font-size: 16px;
  }
  #button_fg {
    font-size: 16px;
  }
}

@media (min-width: 1500px) {
  #button_fg {
    font-size: 18px;
  }
  #box_fg {
    font-size: 18px;
  }
}

@media (min-width: 2000px) {
  #button_fg {
    font-size: 24px;
  }
  #box_fg {
    font-size: 24px;
  }
}

<button id="button_fg">Forecast Gif</button>

  Starting Hour:
  <select id="dropdown_fg">
    <option id="dropdown_fg" value="">Select Hour</option>
    <option value="0">0</option>
    <option value="6">6</option>
    <option value="12">12</option>
    <option value="18">18</option>
    <option value="24">24</option>
    <option value="30">30</option>
    <option value="36">36</option>
    <option value="42">42</option>

  </select>

    Ending Hour:
    <select id="dropdown_fg2">
      <option id="dropdown_fg2" value="">Select Hour</option>
      <option value="6">6</option>
      <option value="12">12</option>
      <option value="18">18</option>
      <option value="24">24</option>
      <option value="30">30</option>
      <option value="36">36</option>
      <option value="42">42</option>
      <option value="48">48</option>

    </select>

    <button id="download-button2">Download GIF</button>


问:
Can I combine In-App purchases and Apple Pay in same app?
we want to develop an iPhone IOS app that will have 3 sections/uses and we would like your opinion if it can all be done and allowed by Apple within the same IOS App, namely:
Section A) Unlocking of Premium software features within the App: This is quite straightforward, as per Apple's guidelines, this has to be through In-App Purchases.
Section B) Selling of an insurance package to end-user:
Section C) And finally, we want to incorporate in the same app, an eStore for the sale of related merchandise:

Question 1) Can In-App Purchase and Apple Pay be used in the same iOS App?
Question 2) For Section B-Insurance. Can ApplePay be used as it is forbidden as an In-App purchase as per Apple’s guidelines?
Question 3) Another requirement would be that pursuant to the sale of the insurance package, we would need to unlock without any charge the Premium features above, can this be done remotely via our back-end or will it be seen by Apple as a way to circumvent the In-App Purchase process if the premium features were paid via ApplePay?
Question 4) For the eStore, I presume that ApplePay or any other payment provider could do the job here?

Any guidance/comments would be greatly appreciated.

Season's greetings!

Richard


问:
How to manage auto scale pods in kuberneted openshift deploeyments?
I want to create 6 pods using kubernetes with openshift. So my scenerio is like following.

each pods are different tasks, each of gets data from different remote databases.

run only two pods at a time, and when those two pods are finished, they will be down and the next two pods will work

is this possible?


问:
HttpClient fails when running Angular application with Server-Side Rendering (Angular Universal)
I have a FastAPI Rest-ful application running on port 8000. I also have an Angular v14 application running locally on port 4200. The Angular application communicates with the Rest-ful application via HttpClient.

The Angular application can run with ng serve (Client-Side Rendering, CSR) or npm run dev:ssr (Server-Side Rendering, SSR). When I run the Angular application via CSR or SSR using a browser everything is good (page renders, no errors in the browser console). However, when I issue a curl command using SSR I get errors.

```<code>curl http://localhost:4200
</code>```

The error I see (as printed to the terminal) is as follows. This error message is not helpful as I have no idea if the problem is on the client or server side. A lot of posts indicates this is a CORS issue, but other articles suggest this type of error means the HTTP request did not even get executed.

```<code>HttpErrorResponse {
  headers: HttpHeaders {
    normalizedNames: Map(0) {},
    lazyUpdate: null,
    headers: Map(0) {}
  },
  status: 0,
  statusText: 'Unknown Error',
  url: 'http://localhost:8000/lucky',
  ok: false,
  name: 'HttpErrorResponse',
  message: 'Http failure response for http://localhost:8000/lucky: 0 Unknown Error',
  error: ProgressEvent {
    type: 'error',
    target: XMLHttpRequest {
      onloadstart: null,
      onprogress: null,
      onabort: null,
      onerror: null,
      onload: null,
      ontimeout: null,
      onloadend: null,
      _listeners: [Object],
      onreadystatechange: null,
      _anonymous: undefined,
      readyState: 4,
      response: null,
      responseText: '',
      responseType: 'text',
      responseURL: '',
      status: 0,
      statusText: '',
      timeout: 0,
      upload: [XMLHttpRequestUpload],
      _method: 'GET',
      _url: [Url],
      _sync: false,
      _headers: [Object],
      _loweredHeaders: [Object],
      _mimeOverride: null,
      _request: null,
      _response: null,
      _responseParts: null,
      _responseHeaders: null,
      _aborting: null,
      _error: null,
      _loadedBytes: 0,
      _totalBytes: 0,
      _lengthComputable: false
    },
    currentTarget: XMLHttpRequest {
      onloadstart: null,
      onprogress: null,
      onabort: null,
      onerror: null,
      onload: null,
      ontimeout: null,
      onloadend: null,
      _listeners: [Object],
      onreadystatechange: null,
      _anonymous: undefined,
      readyState: 4,
      response: null,
      responseText: '',
      responseType: 'text',
      responseURL: '',
      status: 0,
      statusText: '',
      timeout: 0,
      upload: [XMLHttpRequestUpload],
      _method: 'GET',
      _url: [Url],
      _sync: false,
      _headers: [Object],
      _loweredHeaders: [Object],
      _mimeOverride: null,
      _request: null,
      _response: null,
      _responseParts: null,
      _responseHeaders: null,
      _aborting: null,
      _error: null,
      _loadedBytes: 0,
      _totalBytes: 0,
      _lengthComputable: false
    },
    lengthComputable: false,
    loaded: 0,
    total: 0
  }
}
</code>```

My FastAPI application is very simple. As you can see, I have enabled CORS and I basically have only 1 GET endpoint. This application is stored in a single file main.py and run in the terminal as uvicorn main:app --reload.

```<code>from random import randint

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

@app.get('/')
def read_root():
    return {'hello': 'world'}

@app.get('/lucky')
def get_lucky_number():
    return {
        'luckyNumber': randint(0, 10)
    }

app.add_middleware(
    CORSMiddleware,
    allow_origins=['*'],
    allow_credentials=True,
    allow_methods=['*'],
    allow_headers=['*']
)
</code>```

The Angular application is also very simple. I use the following commands to create the application and add Angular Universal.

```<code>ng new web
ng add @nguniversal/express-engine@14.2.0
</code>```

I don't touch anything other than app.component.html and app.component.ts. For  the HTML, my code is as follows.

```<code><h1>Hello, world</h1>
<h2>{{lucky.luckyNumber}}</h2>
<button (click)="nextNumber()">Next</button>
<router-outlet></router-outlet>
</code>```

For the TypeScript, my code is as follows.

```<code>import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';

export interface Lucky {
  luckyNumber: number;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  lucky: Lucky;

  constructor(private readonly http: HttpClient) {
    this.lucky = {
      luckyNumber: -1
    }
  }

  ngOnInit(): void {
    this.nextNumber();
  }

  nextNumber(): void {
    this.http.get<Lucky>('http://localhost:8000/lucky')
      .subscribe(
        r => this.lucky = r,
        e => console.error(e)
      )
  }
}
</code>```

When I run the Angular application with CSR and issue a curl command, I get the following output. I see no errors reported in the terminal

```<code><!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Web</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.css"></head>
<body>
  <app-root></app-root>
<script src="runtime.js" type="module"></script><script src="polyfills.js" type="module"></script><script src="styles.js" defer></script><script src="vendor.js" type="module"></script><script src="main.js" type="module"></script></body>
</html>
</code>```

When I run the Angular application with SSR, and issue a curl command, I see the following output.

```<code><!DOCTYPE html><html lang="en"><head>
  <meta charset="utf-8">
  <title>Web</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.css"></noscript><style ng-transition="serverApp">
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJhcHAuY29tcG9uZW50LnNjc3MifQ== */</style></head>
<body>
  <app-root _nghost-sc17="" ng-version="14.2.12" ng-server-context="other"><h1 _ngcontent-sc17="">Hello, world</h1><h2 _ngcontent-sc17="">-1</h2><button _ngcontent-sc17="">Next</button><router-outlet _ngcontent-sc17=""></router-outlet><!--container--></app-root>
<script src="runtime.js" type="module"></script><script src="polyfills.js" type="module"></script><script src="vendor.js" type="module"></script><script src="main.js" type="module"></script>
</code>```

If you compare the CSR and SSR outputs, clearly, the SSR is rendering on the server but the HttpClient requests are failing (reported in terminal).

The FastAPI and Angular applications are not running in Docker containers; both are run from the terminal and manually as specified. CORS has been enabled with FastAPI.

Any idea on what's wrong?

You might ask, why are you testing with curl and not a browser? Well, I am testing with a browser too, and there is absolutely no issue with CSR or SSR. There is only an issue when I run Angular in SSR mode and use curl to test. I use curl to test because I want to see the fully rendered page as a crawler might (eg open graph og tags, SEO, meta tags).

Body:
I have a FastAPI Rest-ful application running on port 8000. I also have an Angular v14 application running locally on port 4200. The Angular application communicates with the Rest-ful application via HttpClient.

The Angular application can run with ng serve (Client-Side Rendering, CSR) or npm run dev:ssr (Server-Side Rendering, SSR). When I run the Angular application via CSR or SSR using a browser everything is good (page renders, no errors in the browser console). However, when I issue a curl command using SSR I get errors.

curl http://localhost:4200

The error I see (as printed to the terminal) is as follows. This error message is not helpful as I have no idea if the problem is on the client or server side. A lot of posts indicates this is a CORS issue, but other articles suggest this type of error means the HTTP request did not even get executed.

HttpErrorResponse {
  headers: HttpHeaders {
    normalizedNames: Map(0) {},
    lazyUpdate: null,
    headers: Map(0) {}
  },
  status: 0,
  statusText: 'Unknown Error',
  url: 'http://localhost:8000/lucky',
  ok: false,
  name: 'HttpErrorResponse',
  message: 'Http failure response for http://localhost:8000/lucky: 0 Unknown Error',
  error: ProgressEvent {
    type: 'error',
    target: XMLHttpRequest {
      onloadstart: null,
      onprogress: null,
      onabort: null,
      onerror: null,
      onload: null,
      ontimeout: null,
      onloadend: null,
      _listeners: [Object],
      onreadystatechange: null,
      _anonymous: undefined,
      readyState: 4,
      response: null,
      responseText: '',
      responseType: 'text',
      responseURL: '',
      status: 0,
      statusText: '',
      timeout: 0,
      upload: [XMLHttpRequestUpload],
      _method: 'GET',
      _url: [Url],
      _sync: false,
      _headers: [Object],
      _loweredHeaders: [Object],
      _mimeOverride: null,
      _request: null,
      _response: null,
      _responseParts: null,
      _responseHeaders: null,
      _aborting: null,
      _error: null,
      _loadedBytes: 0,
      _totalBytes: 0,
      _lengthComputable: false
    },
    currentTarget: XMLHttpRequest {
      onloadstart: null,
      onprogress: null,
      onabort: null,
      onerror: null,
      onload: null,
      ontimeout: null,
      onloadend: null,
      _listeners: [Object],
      onreadystatechange: null,
      _anonymous: undefined,
      readyState: 4,
      response: null,
      responseText: '',
      responseType: 'text',
      responseURL: '',
      status: 0,
      statusText: '',
      timeout: 0,
      upload: [XMLHttpRequestUpload],
      _method: 'GET',
      _url: [Url],
      _sync: false,
      _headers: [Object],
      _loweredHeaders: [Object],
      _mimeOverride: null,
      _request: null,
      _response: null,
      _responseParts: null,
      _responseHeaders: null,
      _aborting: null,
      _error: null,
      _loadedBytes: 0,
      _totalBytes: 0,
      _lengthComputable: false
    },
    lengthComputable: false,
    loaded: 0,
    total: 0
  }
}

My FastAPI application is very simple. As you can see, I have enabled CORS and I basically have only 1 GET endpoint. This application is stored in a single file main.py and run in the terminal as uvicorn main:app --reload.

from random import randint

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

@app.get('/')
def read_root():
    return {'hello': 'world'}

@app.get('/lucky')
def get_lucky_number():
    return {
        'luckyNumber': randint(0, 10)
    }

app.add_middleware(
    CORSMiddleware,
    allow_origins=['*'],
    allow_credentials=True,
    allow_methods=['*'],
    allow_headers=['*']
)

The Angular application is also very simple. I use the following commands to create the application and add Angular Universal.

ng new web
ng add @nguniversal/express-engine@14.2.0

I don't touch anything other than app.component.html and app.component.ts. For  the HTML, my code is as follows.

Hello, world

{{lucky.luckyNumber}}

<button (click)="nextNumber()">Next</button>
<router-outlet></router-outlet>

For the TypeScript, my code is as follows.

import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';

export interface Lucky {
  luckyNumber: number;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  lucky: Lucky;

  constructor(private readonly http: HttpClient) {
    this.lucky = {
      luckyNumber: -1
    }
  }

  ngOnInit(): void {
    this.nextNumber();
  }

  nextNumber(): void {
    this.http.get<Lucky>('http://localhost:8000/lucky')
      .subscribe(
        r => this.lucky = r,
        e => console.error(e)
      )
  }
}

When I run the Angular application with CSR and issue a curl command, I get the following output. I see no errors reported in the terminal

<!doctype html>

  <meta charset="utf-8">
  <title>Web</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.css">

  <app-root></app-root>

When I run the Angular application with SSR, and issue a curl command, I see the following output.

<!DOCTYPE html>
  <meta charset="utf-8">
  <title>Web</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="styles.css">

  <app-root _nghost-sc17="" ng-version="14.2.12" ng-server-context="other">
Hello, world

-1
<button _ngcontent-sc17="">Next</button><router-outlet _ngcontent-sc17=""></router-outlet></app-root>

If you compare the CSR and SSR outputs, clearly, the SSR is rendering on the server but the HttpClient requests are failing (reported in terminal).

The FastAPI and Angular applications are not running in Docker containers; both are run from the terminal and manually as specified. CORS has been enabled with FastAPI.

Any idea on what's wrong?

You might ask, why are you testing with curl and not a browser? Well, I am testing with a browser too, and there is absolutely no issue with CSR or SSR. There is only an issue when I run Angular in SSR mode and use curl to test. I use curl to test because I want to see the fully rendered page as a crawler might (eg open graph og tags, SEO, meta tags).


问:
Rewrite category slug in wordpress not working
Been looking to get a rewrite og a category slug in wordpress to work
and found this code and some similar ones one the net...
I have a category named "lyrics" I want to rewrite to something like "theCategory/lyrics"
But the code doesnt work

Here is the code

```<code>function fix_cat_slug( $taxonomy, $object_type, $args){
    if( $taxonomy == 'lyrics'){
        remove_action( current_action(), __FUNCTION__ );
        $args['rewrite'] = array( 'slug' => 'new-slug' );
        register_taxonomy( $taxonomy, $object_type, $args );
    }
}
add_action( 'registered_taxonomy', 'fix_cat_slug', 10, 3);
</code>```

IF I change if( $taxonomy == 'lyrics'){ to if( $taxonomy == 'category'){
It changes all category slugs and if I do if( $taxonomy != 'lyrics'){
It's the same, so apparently the code seems like it's just checking if it IS a categoy, not the name of the category....

Any help as to how I do this?

Body:
Been looking to get a rewrite og a category slug in wordpress to work
and found this code and some similar ones one the net...
I have a category named "lyrics" I want to rewrite to something like "theCategory/lyrics"
But the code doesnt work

Here is the code

function fix_cat_slug( $taxonomy, $object_type, $args){
    if( $taxonomy == 'lyrics'){
        remove_action( current_action(), __FUNCTION__ );
        $args['rewrite'] = array( 'slug' => 'new-slug' );
        register_taxonomy( $taxonomy, $object_type, $args );
    }
}
add_action( 'registered_taxonomy', 'fix_cat_slug', 10, 3);

IF I change if( $taxonomy == 'lyrics'){ to if( $taxonomy == 'category'){
It changes all category slugs and if I do if( $taxonomy != 'lyrics'){
It's the same, so apparently the code seems like it's just checking if it IS a categoy, not the name of the category....

Any help as to how I do this?


问:
How to use html.render inside a thread?
When trying to send a function to the stream that parses the page and then executes the html.render, an error occurs:
Error: There is no current event loop in thread 'Thread-1 (take_proxy_us_spys_one_thread)
I started talking about a similar problem and realized that a friend here somehow managed to implement this. But I still get an error.

Here is my code which should be repeated all the time.
Help, please, to understand.

```<code>import urllib3
import requests
import time
from requests_html import HTMLSession
import threading
import fake_useragent

def take_proxy_us_spys_one(urls: list=[], header:dict = None,):
    for url in urls:
        try:
            url_first = 'https://spys.one'
            r = requests.get(url_first, headers=header)
            cookies = r.cookies
            session = HTMLSession()
            r = session.post(url,
                             data={'xx00': '','xpp': '5','xf1': '0','xf2': '0','xf3': '0','xf4': '0', 'xf5': '0'},
                             headers=header,
                             cookies=cookies)
            r.html.render(reload=False,)
            print(str(r))
        except Exception as exc:
            print("Error: " + str(exc))

def take_proxy_us_spys_one_thread(event, sleeptime= 60, urls=[], lock = None):
    while event.is_set():
        try:
            user = fake_useragent.UserAgent().random
            header = {'User-Agent': user}
            lock.acquire() if lock!=None else None
            proxies_1 = take_proxy_us_spys_one(urls=urls, header=header)
            lock.release() if lock != None else None
            time.sleep(sleeptime)
        except Exception as exc:
            print("Error: " + str(exc))
            time.sleep(sleeptime)

if __name__ == '__main__':
    start_in_thread = True
    urllib3.disable_warnings()

    urls_spys_one = [
        'https://spys.one/free-proxy-list/ALL/'
    ]

    lock = threading.Lock()
    event = threading.Event()
    event.set()

    t2 = threading.Thread(target=take_proxy_us_spys_one_thread, args=(event, 10, urls_spys_one, lock),).start()
</code>```

I tried to implement the mechanism from here.

Title: How to use html.render inside a thread?

Body:
When trying to send a function to the stream that parses the page and then executes the html.render, an error occurs:
Error: There is no current event loop in thread 'Thread-1 (take_proxy_us_spys_one_thread)
I started talking about a similar problem and realized that a friend here somehow managed to implement this. But I still get an error.

Here is my code which should be repeated all the time.
Help, please, to understand.

import urllib3
import requests
import time
from requests_html import HTMLSession
import threading
import fake_useragent

def take_proxy_us_spys_one(urls: list=[], header:dict = None,):
    for url in urls:
        try:
            url_first = 'https://spys.one'
            r = requests.get(url_first, headers=header)
            cookies = r.cookies
            session = HTMLSession()
            r = session.post(url,
                             data={'xx00': '','xpp': '5','xf1': '0','xf2': '0','xf3': '0','xf4': '0', 'xf5': '0'},
                             headers=header,
                             cookies=cookies)
            r.html.render(reload=False,)
            print(str(r))
        except Exception as exc:
            print("Error: " + str(exc))

def take_proxy_us_spys_one_thread(event, sleeptime= 60, urls=[], lock = None):
    while event.is_set():
        try:
            user = fake_useragent.UserAgent().random
            header = {'User-Agent': user}
            lock.acquire() if lock!=None else None
            proxies_1 = take_proxy_us_spys_one(urls=urls, header=header)
            lock.release() if lock != None else None
            time.sleep(sleeptime)
        except Exception as exc:
            print("Error: " + str(exc))
            time.sleep(sleeptime)

if __name__ == '__main__':
    start_in_thread = True
    urllib3.disable_warnings()

    urls_spys_one = [
        'https://spys.one/free-proxy-list/ALL/'
    ]

    lock = threading.Lock()
    event = threading.Event()
    event.set()

    t2 = threading.Thread(target=take_proxy_us_spys_one_thread, args=(event, 10, urls_spys_one, lock),).start()

I tried to implement the mechanism from here.


问:
Why I can't see my props from backend in my nuxt page?
I'm making an index page nad I have to recover from my db customers data and insert it in a table element in my index page.
I've set my props, mounted function with axios that get the data from the backend route and in a data function I return customers array,

my index.vue page:

<template>

    name
    address

    {{ customers.name }}
    {{ customers.address }}

</template>

```

if I write {{ customers }} the function return the list of customers fields but when I search for a specific data (for example {{ customers.name }}) it don't return me nothing, even errors.

Obviously I've set baseurl in nuxt.config with address of my laravel app

Body:
I'm making an index page nad I have to recover from my db customers data and insert it in a table element in my index page.
I've set my props, mounted function with axios that get the data from the backend route and in a data function I return customers array,

my index.vue page:

<template>

    name
    address

    {{ customers.name }}
    {{ customers.address }}

</template>

if I write {{ customers }} the function return the list of customers fields but when I search for a specific data (for example {{ customers.name }}) it don't return me nothing, even errors.

Obviously I've set baseurl in nuxt.config with address of my laravel app


问:
showing the photos from a folder
I am using Jupyter notebook.
I have written a program that converts my video into some frames. For example frame001, frame002, ...., frame030 in the directory/data/....

Now I want to write a command to show the photos from the folder in order. After I press escape, the frame is closed and next frame is shown aromatically until the last frame.

Any help would be appreciated.

Best kinds
Vahid

I want to write a command to show the photos from the folder in order. After I press escape, the frame is closed and next frame is shown aromatically until the last frame.

Title: showing the photos from a folder


问:
How to output terragrunt dependencies with Splat Expression
I am new to terragrunt and terraform. My TF module pretty much creates a NLB, EIP, listeners, target groups and I just added the target group attachment to the module.
I am deploying the stacks with terragrunt. In my terragrunt configuration files I have a folder called main and that folder has many others subfolders public_* with their terragrunt files.
When I run a plan on the terragrunt below it run smoothly and passes the plan however only ../public_2 output is listed when I expect all the outputs listed in public_*. I know I am close and really appreciate any feedback.

My terragrunt:

```<code>terraform {
  source = "git::https://repo.test-elb-attachment"
}

include {
  path = find_in_parent_folders()
}

dependency "test" {
  config_path = "../../../test"
  mock_outputs = {
    vpc_id             = "vpc-12345"
    private_subnet_ids = ["subnet-1", "subnet-2"]
  }
}

# my test dependencies
dependency "main" {
  config_path = "../public_1"
}

dependency "main" {
  config_path = "../public_2"
}
# inputs
inputs = {
  name = "mytest"
  tags = {
    env        = "mytest"
    deployment = "mytest"
  }
  subnets   = dependency.test.outputs.private_subnet_ids
  vpc_id    = dependency.test.outputs.vpc_id
  target_id = dependency.main[*].outputs.instance_id # outputs public_2 only!
  ...
</code>```

Body:
I am new to terragrunt and terraform. My TF module pretty much creates a NLB, EIP, listeners, target groups and I just added the target group attachment to the module.
I am deploying the stacks with terragrunt. In my terragrunt configuration files I have a folder called main and that folder has many others subfolders public_* with their terragrunt files.
When I run a plan on the terragrunt below it run smoothly and passes the plan however only ../public_2 output is listed when I expect all the outputs listed in public_*. I know I am close and really appreciate any feedback.

My terragrunt:

terraform {
  source = "git::https://repo.test-elb-attachment"
}

include {
  path = find_in_parent_folders()
}

dependency "test" {
  config_path = "../../../test"
  mock_outputs = {
    vpc_id             = "vpc-12345"
    private_subnet_ids = ["subnet-1", "subnet-2"]
  }
}

# my test dependencies
dependency "main" {
  config_path = "../public_1"
}

dependency "main" {
  config_path = "../public_2"
}
# inputs
inputs = {
  name = "mytest"
  tags = {
    env        = "mytest"
    deployment = "mytest"
  }
  subnets   = dependency.test.outputs.private_subnet_ids
  vpc_id    = dependency.test.outputs.vpc_id
  target_id = dependency.main[*].outputs.instance_id # outputs public_2 only!
  ...


问:
Parse error: syntax error, unexpected 'break'

<?php
    #[\ReturnTypeWillChange]
    public function write($session_id, $session_data)
    {
        // If the two IDs don't match, we have a session_regenerate_id() call
        // and we need to close the old handle and open a new one
        if ($session_id !== $this->_session_id && ($this->close() === $this->_failure OR $this->read($session_id) === $this->_failure))
        {
            return $this->_failure;
        }

        if ( ! is_resource($this->_file_handle))
        {
            return $this->_failure;
        }
        elseif ($this->_fingerprint === md5($session_data))
        {
            return ( ! $this->_file_new && ! touch($this->_file_path.$session_id))
                ? $this->_failure
                : $this->_success;
        }

        if ( ! $this->_file_new)
        {
            ftruncate($this->_file_handle, 0);
            rewind($this->_file_handle);
        }

        if (($length = strlen($session_data)) > 0)
        {
            for ($written = 0; $written < $length; $written += $result)
            {
                if (($result = fwrite($this->_file_handle, substr($session_data, $written))) === FALSE)
                {
                    break;
                }
            }
            if ( ! is_int($result))
            {
                $this->_fingerprint = md5(substr($session_data, 0, $written));
                log_message('error', 'Session: Unable to write data.');
                return $this->_failure;
            }
        }

        $this->_fingerprint = md5($session_data);
        return $this->_success;
    }
```

Message: syntax error, unexpected token "break"

What am I doing wrong here? Is there perhaps a problem somewhere else that could make this "unexpected break" error show up?

Body:
<?php
    #[\ReturnTypeWillChange]
    public function write($session_id, $session_data)
    {
        // If the two IDs don't match, we have a session_regenerate_id() call
        // and we need to close the old handle and open a new one
        if ($session_id !== $this->_session_id && ($this->close() === $this->_failure OR $this->read($session_id) === $this->_failure))
        {
            return $this->_failure;
        }

        if ( ! is_resource($this->_file_handle))
        {
            return $this->_failure;
        }
        elseif ($this->_fingerprint === md5($session_data))
        {
            return ( ! $this->_file_new && ! touch($this->_file_path.$session_id))
                ? $this->_failure
                : $this->_success;
        }

        if ( ! $this->_file_new)
        {
            ftruncate($this->_file_handle, 0);
            rewind($this->_file_handle);
        }

        if (($length = strlen($session_data)) > 0)
        {
            for ($written = 0; $written < $length; $written += $result)
            {
                if (($result = fwrite($this->_file_handle, substr($session_data, $written))) === FALSE)
                {
                    break;
                }
            }
            if ( ! is_int($result))
            {
                $this->_fingerprint = md5(substr($session_data, 0, $written));
                log_message('error', 'Session: Unable to write data.');
                return $this->_failure;
            }
        }

        $this->_fingerprint = md5($session_data);
        return $this->_success;
    }

Message: syntax error, unexpected token "break"

What am I doing wrong here? Is there perhaps a problem somewhere else that could make this "unexpected break" error show up?


问:
Having trouble creating a mask to plot coordinates on a map
I have been working on this dataset for a while now trying to plot some coordinates on a simple map of the US to create a density map. I easily created the map in Tableau, but I want to be able to make a similar map in Python. The following picture is the end-goal made in Tableau:

Below is what I have coded so far. I believe I have gotten around needing to mask this dataset as I have stripped out everything but the contiguous US, but I would like to know how to create a mask in the future to save time and have more options.

```<code>import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from datetime import timedelta, date
import matplotlib
from pandas import Series, DataFrame

import geopandas as gpd
from geopandas import GeoDataFrame
from shapely.geometry import Point, mapping
from rasterio import mask as msk
import fiona

# import data
df = pd.read_csv('./Data/complete.csv', on_bad_lines='skip') # csv had some bad data, had to skip

df = df.drop('Unnamed: 11', axis=1)

# remove Canadian provinces (and nulls) using list of states (including DC)
# remove AK and HI since only plotting contiguous US
list_of_states = ['AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',
           'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',
           'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',
           'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
           'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']

df['state'] = df['state'].str.upper() # convert column to uppercase
df = df[df['state'].isin(list_of_states)]
df = df[df['country'].isin(['us'])]

# clean the data
# remove values that contain '/' and 'q'
df = df.drop(df[df.latitude.str.contains(r'[/q]')].index)

# convert lat/long to float
df['latitude'] = df.latitude.astype('float')
df['longitude'] = df.longitude.astype('float')
</code>```

A sample of my data:

```<code># import shapefile
us_map = gpd.read_file(r'./Data/USA_States_(Generalized)/USA_States_Generalized.shp')

#remove AK and HI
us_map = us_map[~us_map['STATE_NAME'].isin(['Alaska', 'Hawaii'])]

# create geodataframe of lats and longs
geometry = [Point(xy) for xy in zip(df['longitude'], df['latitude'])]
points = GeoDataFrame(df, geometry=geometry)
</code>```

This is where I am unsure of the best path as each path is giving me trouble. I have tried using Fiona and rasterio to create a mask (see below), but the I cannot figure out how to fix my AttributeError.

```<code>with fiona.open('./Data/USA_States_(Generalized)/USA_States_Generalized.shp', 'r') as shapefile:
    for feature in shapefile:
        shapes = [feature['geometry']]

us_array = msk.mask(points.geometry, us_map, shapes, crop=True)
</code>```

The error:

```<code>AttributeError                            Traceback (most recent call last)
/var/folders/ll/77znv_6d7jng9_kjkpdllhbh0000gn/T/ipykernel_2471/3613015337.py in <module>
      4         shapes = [feature['geometry']]
      5
----> 6 us_array = msk.mask(points.geometry, us_map, shapes, crop=True)

~/opt/anaconda3/envs/PopulationDensity/lib/python3.7/site-packages/rasterio/mask.py in mask(dataset, shapes, all_touched, invert, nodata, filled, crop, pad, pad_width, indexes)
    171
    172     if nodata is None:
--> 173         if dataset.nodata is not None:
    174             nodata = dataset.nodata
    175         else:

~/opt/anaconda3/envs/PopulationDensity/lib/python3.7/site-packages/pandas/core/generic.py in __getattr__(self, name)
   5485         ):
   5486             return self[name]
-> 5487         return object.__getattribute__(self, name)
   5488
   5489     def __setattr__(self, name: str, value) -> None:

AttributeError: 'GeoSeries' object has no attribute 'nodata'
</code>```

The rasterio documentation states the first argument must be a raster, so I then tried to convert my dataframe to a raster using the following:

```<code># need to convert coords to raster so fiona will work?
# last line not working

import xarray as xr
import rioxarray

da = df.set_index('ID').to_xarray()

# promote the data variables model lat/long to 2d coordinates
da = da.set_coords(['latitude', 'longitude'])
da.rio.to_raster('./Data/UFO_Sightings_Coords_Shapefile.shp')
</code>```

with an error following:

```<code>MissingSpatialDimensionError              Traceback (most recent call last)
/var/folders/ll/77znv_6d7jng9_kjkpdllhbh0000gn/T/ipykernel_2471/1071145538.py in <module>
      9 # promote the data variables model lat/long to 2d coordinates
     10 da = da.set_coords(['latitude', 'longitude'])
---> 11 da.rio.to_raster('./Data/UFO_Sightings_Coords_Shapefile.shp')

~/opt/anaconda3/envs/PopulationDensity/lib/python3.7/site-packages/rioxarray/raster_dataset.py in to_raster(self, raster_path, driver, dtype, tags, windowed, recalc_transform, lock, compute, **profile_kwargs)
    477         # write it to a raster
    478         return data_array.rio.set_spatial_dims(
--> 479             x_dim=self.x_dim,
    480             y_dim=self.y_dim,
    481             inplace=True,

~/opt/anaconda3/envs/PopulationDensity/lib/python3.7/site-packages/rioxarray/rioxarray.py in x_dim(self)
    790             return self._x_dim
    791         raise MissingSpatialDimensionError(
--> 792             "x dimension not found. 'rio.set_spatial_dims()' or "
    793             "using 'rename()' to change the dimension name to 'x' can address this."
    794             f"{_get_data_var_message(self._obj)}"

MissingSpatialDimensionError: x dimension not found. 'rio.set_spatial_dims()' or using 'rename()' to change the dimension name to 'x' can address this.
</code>```

I'm not sure where to go from here.

Body:
I have been working on this dataset for a while now trying to plot some coordinates on a simple map of the US to create a density map. I easily created the map in Tableau, but I want to be able to make a similar map in Python. The following picture is the end-goal made in Tableau:

Below is what I have coded so far. I believe I have gotten around needing to mask this dataset as I have stripped out everything but the contiguous US, but I would like to know how to create a mask in the future to save time and have more options.

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from datetime import timedelta, date
import matplotlib
from pandas import Series, DataFrame

import geopandas as gpd
from geopandas import GeoDataFrame
from shapely.geometry import Point, mapping
from rasterio import mask as msk
import fiona

# import data
df = pd.read_csv('./Data/complete.csv', on_bad_lines='skip') # csv had some bad data, had to skip

df = df.drop('Unnamed: 11', axis=1)

# remove Canadian provinces (and nulls) using list of states (including DC)
# remove AK and HI since only plotting contiguous US
list_of_states = ['AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'GA',
           'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME',
           'MI', 'MN', 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM',
           'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
           'UT', 'VA', 'VT', 'WA', 'WI', 'WV', 'WY']

df['state'] = df['state'].str.upper() # convert column to uppercase
df = df[df['state'].isin(list_of_states)]
df = df[df['country'].isin(['us'])]

# clean the data
# remove values that contain '/' and 'q'
df = df.drop(df[df.latitude.str.contains(r'[/q]')].index)

# convert lat/long to float
df['latitude'] = df.latitude.astype('float')
df['longitude'] = df.longitude.astype('float')

A sample of my data:

# import shapefile
us_map = gpd.read_file(r'./Data/USA_States_(Generalized)/USA_States_Generalized.shp')

#remove AK and HI
us_map = us_map[~us_map['STATE_NAME'].isin(['Alaska', 'Hawaii'])]

# create geodataframe of lats and longs
geometry = [Point(xy) for xy in zip(df['longitude'], df['latitude'])]
points = GeoDataFrame(df, geometry=geometry)

This is where I am unsure of the best path as each path is giving me trouble. I have tried using Fiona and rasterio to create a mask (see below), but the I cannot figure out how to fix my AttributeError.

with fiona.open('./Data/USA_States_(Generalized)/USA_States_Generalized.shp', 'r') as shapefile:
    for feature in shapefile:
        shapes = [feature['geometry']]

us_array = msk.mask(points.geometry, us_map, shapes, crop=True)

The error:

AttributeError                            Traceback (most recent call last)
/var/folders/ll/77znv_6d7jng9_kjkpdllhbh0000gn/T/ipykernel_2471/3613015337.py in <module>
      4         shapes = [feature['geometry']]
      5
----> 6 us_array = msk.mask(points.geometry, us_map, shapes, crop=True)

~/opt/anaconda3/envs/PopulationDensity/lib/python3.7/site-packages/rasterio/mask.py in mask(dataset, shapes, all_touched, invert, nodata, filled, crop, pad, pad_width, indexes)
    171
    172     if nodata is None:
--> 173         if dataset.nodata is not None:
    174             nodata = dataset.nodata
    175         else:

~/opt/anaconda3/envs/PopulationDensity/lib/python3.7/site-packages/pandas/core/generic.py in __getattr__(self, name)
   5485         ):
   5486             return self[name]
-> 5487         return object.__getattribute__(self, name)
   5488
   5489     def __setattr__(self, name: str, value) -> None:

AttributeError: 'GeoSeries' object has no attribute 'nodata'

The rasterio documentation states the first argument must be a raster, so I then tried to convert my dataframe to a raster using the following:

# need to convert coords to raster so fiona will work?
# last line not working

import xarray as xr
import rioxarray

da = df.set_index('ID').to_xarray()

# promote the data variables model lat/long to 2d coordinates
da = da.set_coords(['latitude', 'longitude'])
da.rio.to_raster('./Data/UFO_Sightings_Coords_Shapefile.shp')

with an error following:

MissingSpatialDimensionError              Traceback (most recent call last)
/var/folders/ll/77znv_6d7jng9_kjkpdllhbh0000gn/T/ipykernel_2471/1071145538.py in <module>
      9 # promote the data variables model lat/long to 2d coordinates
     10 da = da.set_coords(['latitude', 'longitude'])
---> 11 da.rio.to_raster('./Data/UFO_Sightings_Coords_Shapefile.shp')

~/opt/anaconda3/envs/PopulationDensity/lib/python3.7/site-packages/rioxarray/raster_dataset.py in to_raster(self, raster_path, driver, dtype, tags, windowed, recalc_transform, lock, compute, **profile_kwargs)
    477         # write it to a raster
    478         return data_array.rio.set_spatial_dims(
--> 479             x_dim=self.x_dim,
    480             y_dim=self.y_dim,
    481             inplace=True,

~/opt/anaconda3/envs/PopulationDensity/lib/python3.7/site-packages/rioxarray/rioxarray.py in x_dim(self)
    790             return self._x_dim
    791         raise MissingSpatialDimensionError(
--> 792             "x dimension not found. 'rio.set_spatial_dims()' or "
    793             "using 'rename()' to change the dimension name to 'x' can address this."
    794             f"{_get_data_var_message(self._obj)}"

MissingSpatialDimensionError: x dimension not found. 'rio.set_spatial_dims()' or using 'rename()' to change the dimension name to 'x' can address this.

I'm not sure where to go from here.


问:
Unsure why record contents aren't being removed (socket.io)
I'm attempting to create a chat app using socket.io. I've managed to update the rooms whenever the user adds one by means of having a record kept on the back end. However, when I use similar logic, I can't get my button clicking on the front end to remove the room and all those like it on the back end.

Here's my code for the Rooms component (where I generate the contents of my record and show each room and where I have the button and the function to remove the specific room):

```<code>export function Rooms() {
  useEffect(() => {
    socket.emit(EVENTS.CLIENT.ON_LOAD);
  }, []);

  const { socket, roomId, rooms } = useSockets();
  const newRoomRef = useRef<any>(null);

  function handleCreateRoom() {
    const roomName = newRoomRef.current.value;
    // if (!roomName) {
    //   return;
    // }
    if (!String(roomName).trim()) return;

    socket.emit(EVENTS.CLIENT.CREATE_ROOM, { roomName });
    newRoomRef.current.value = "";
  }

  function handleJoinRoom(key: string) {
    if (key === roomId) return;

    socket.emit(EVENTS.CLIENT.JOIN_ROOM, key);
  }

  function handleRemoveRoom(key: string) {
    socket.emit(EVENTS.CLIENT.REMOVE_ROOM, key);

    newRoomRef.current.value = "";
  }
  return (
    <Box
      sx={{

      }}
    >
      <Box
        sx={{

        }}
      >
        <TextField

        />
        <Button

        >
          CREATE ROOM
        </Button>
      </Box>
      <Box

      >
        <Box

        >
          {Object.keys(rooms).map((key) => {
            return (
              <Card

              >
                <Button
                  disabled={roomId === key}
                  onClick={() => handleJoinRoom(key)}
                  sx={{ width: "100%" }}
                >
                  {rooms[key].name}
                </Button>
                <Button
                  sx={{}}
                  onClick={() => handleRemoveRoom(rooms[key].name)}
                >
                  <HighlightOffIcon style={{ color: "red" }} />
                </Button>
              </Card>
            );
          })}
        </Box>
      </Box>
    </Box>
  );
}
</code>```

Here's the logic on my back end to remove a room as well as add rooms (I call the add rooms event from the remove room event so I figured I'd show both):

```<code>let rooms: Record<string, { name: string }> = {};

socket.on(EVENTS.CLIENT.CREATE_ROOM, ({ roomName }) => {
      console.log({ roomName });

      // create a roomId
      const roomId = nanoid();

      // add a new room to the rooms object
      rooms[roomId] = {
        name: roomName,
      };

      socket.join(roomId);

      // broadcast an event saying there is a new room
      socket.broadcast.emit(EVENTS.SERVER.ROOMS, rooms);

      // emit back to the room creator with all the rooms
      socket.emit(EVENTS.SERVER.ROOMS, rooms);

      // emit event back to the room creator saying they have joined a room
      socket.emit(EVENTS.SERVER.JOINED_ROOM, roomId);
    });

    socket.on(EVENTS.CLIENT.REMOVE_ROOM, (value) => {
      let deepCopy = { ...rooms };
      Object.keys(deepCopy).map((key) => {
        if (deepCopy[key].name === value) {
          delete deepCopy[key];
        }
      });
      rooms = { ...deepCopy };
      socket.emit(EVENTS.SERVER.ROOMS, rooms);
    });
</code>```

And in my context, I'm simply updating the rooms state which is also a record:

```<code>  socket.on(EVENTS.SERVER.ROOMS, (value) => {
    // console.log(value);
    setRooms(value);
  });
</code>```

It's my first time working with socket.io, so if you have any other advice, much appreciated.

Just for clarification, adding rooms works, deleting rooms doesn't.

Body:
I'm attempting to create a chat app using socket.io. I've managed to update the rooms whenever the user adds one by means of having a record kept on the back end. However, when I use similar logic, I can't get my button clicking on the front end to remove the room and all those like it on the back end.

Here's my code for the Rooms component (where I generate the contents of my record and show each room and where I have the button and the function to remove the specific room):

export function Rooms() {
  useEffect(() => {
    socket.emit(EVENTS.CLIENT.ON_LOAD);
  }, []);

  const { socket, roomId, rooms } = useSockets();
  const newRoomRef = useRef<any>(null);

  function handleCreateRoom() {
    const roomName = newRoomRef.current.value;
    // if (!roomName) {
    //   return;
    // }
    if (!String(roomName).trim()) return;

    socket.emit(EVENTS.CLIENT.CREATE_ROOM, { roomName });
    newRoomRef.current.value = "";
  }

  function handleJoinRoom(key: string) {
    if (key === roomId) return;

    socket.emit(EVENTS.CLIENT.JOIN_ROOM, key);
  }

  function handleRemoveRoom(key: string) {
    socket.emit(EVENTS.CLIENT.REMOVE_ROOM, key);

    newRoomRef.current.value = "";
  }
  return (
    <Box
      sx={{

      }}
    >
      <Box
        sx={{

        }}
      >
        <TextField

        />
        <Button

        >
          CREATE ROOM
        </Button>
      </Box>
      <Box

      >
        <Box

        >
          {Object.keys(rooms).map((key) => {
            return (
              <Card

              >
                <Button
                  disabled={roomId === key}
                  onClick={() => handleJoinRoom(key)}
                  sx={{ width: "100%" }}
                >
                  {rooms[key].name}
                </Button>
                <Button
                  sx={{}}
                  onClick={() => handleRemoveRoom(rooms[key].name)}
                >
                  <HighlightOffIcon style={{ color: "red" }} />
                </Button>
              </Card>
            );
          })}
        </Box>
      </Box>
    </Box>
  );
}

Here's the logic on my back end to remove a room as well as add rooms (I call the add rooms event from the remove room event so I figured I'd show both):

let rooms: Record<string, { name: string }> = {};

socket.on(EVENTS.CLIENT.CREATE_ROOM, ({ roomName }) => {
      console.log({ roomName });

      // create a roomId
      const roomId = nanoid();

      // add a new room to the rooms object
      rooms[roomId] = {
        name: roomName,
      };

      socket.join(roomId);

      // broadcast an event saying there is a new room
      socket.broadcast.emit(EVENTS.SERVER.ROOMS, rooms);

      // emit back to the room creator with all the rooms
      socket.emit(EVENTS.SERVER.ROOMS, rooms);

      // emit event back to the room creator saying they have joined a room
      socket.emit(EVENTS.SERVER.JOINED_ROOM, roomId);
    });

    socket.on(EVENTS.CLIENT.REMOVE_ROOM, (value) => {
      let deepCopy = { ...rooms };
      Object.keys(deepCopy).map((key) => {
        if (deepCopy[key].name === value) {
          delete deepCopy[key];
        }
      });
      rooms = { ...deepCopy };
      socket.emit(EVENTS.SERVER.ROOMS, rooms);
    });

And in my context, I'm simply updating the rooms state which is also a record:

  socket.on(EVENTS.SERVER.ROOMS, (value) => {
    // console.log(value);
    setRooms(value);
  });

It's my first time working with socket.io, so if you have any other advice, much appreciated.

Just for clarification, adding rooms works, deleting rooms doesn't.


问:
How To Send Multiple Attachments From Google Form Uploaded Files And PDF Caputured Range From Spreadsheet OnSubmit?
What I'm trying to do is onSubmit script in google sheets from a submitted google forms include the uploaded PDFs from google form submittion and area of spreadsheet with some of the conolidated data

I dont know how to combine the url lists from the google form submission where a single cell may contain multile URLs to upload PDF or none at all

```<code>function myFunction() {
  DocumentApp.getActiveDocument();
  DriveApp.getFiles();

  const ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1ELQ-SvRwWRmqDae1xz_-062oIs5RrzsQzYs7zFrCdxk/edit");
  var ss_formUrl = SpreadsheetApp.getActiveSpreadsheet().getFormUrl;
  var ss_dynamic = SpreadsheetApp.getActiveSheet().getSheetId();
  var ccemail = 'bruno.brottes@gmail.com';
  var email = ss.getSheetByName("DATA").getRange("E1").getValue().toString();
  var company = ss.getSheetByName("DATA").getRange("B1").getValue().toString();
  var attachments1 = ss.getSheetByName("DATA").getRange("J1").getValue().toString();
  //MIMETYPE:PDF
  //drive.google.com/open?id=1IpuzbJO3LnSV80iAr6OZ-jSrn5ht7uYT
  var attachments2 = ss.getSheetByName("DATA").getRange("P1").getValue().toString();
  //MIMETYPE:PDF
  //drive.google.com/open?id=1IpuzbJO3LnSV80iAr6OZ-jSrn5ht7uYT
  var attachments3 = ss.getSheetByName("DATA").getRange("V1").getValue().toString();
  //MIMETYPE:PDF
  //drive.google.com/open?id=1lSnyBdfPFWvxVRedZo_SgK6HTLoTfFuA,
  //drive.google.com/open?id=19g8oKib4sSvEVHDAO4IGd1hhJsJ-jY_A,
  //drive.google.com/open?id=1WxOJCD0STFLOQ4Lw0Mw4ZOAQ3OVUx9-k
  var attachments4 = ss.getSheetByName("DATA").getRange("AQ1").getValue().toString();
  //MINETYPE:PDF
  //drive.google.com/open?id=116ijk7n_CdmKWS6Z_aN0IlKJ1vNoeY7I
  var attachments5 = ss.getSheetByName('DATA').getRange('AS1').getValue().toString();
  //MINITYPE:ZIP
  var combinedAttachments = ['attachments1','attachments2','attachments3','attachments4','attachments5'];
  var combinedAll = ss_dynamic.getRange(combinedAttachments);
  var combinedAll = combinedAttachments1.concat(combinedAttachments2).concat(combinedAttachments3).concat(combinedAttachments4);

  for (var i = 0; i < combinedAll.length; i++)
  {
    var files = DriveApp.createFile(combinedAll[i]);
    attachments.push(files);
  }

      if(files){
        var files = files.split(', ');
      }

  const subject = 'Year-End.' + procedure + ".company" + ".pdf";

  const body = "See Attached";

  const url = 'https://docs.google.com/spreadsheets/d/1ELQ-SvRwWRmqDae1xz_-062oIs5RrzsQzYs7zFrCdxk/export?';

 const exportOptions =
     'exportFormat=pdf&format=pdf' + // export as pdf
     '&size=letter' + // paper size letter / You can use A4 or legal
     '&portrait=true' + // orientation portal, use false for landscape
     '&fitw=true' + // fit to page width false, to get the actual size
     '&fith=true' +
     '&top_margin=0.25' +              //All four margins must be set!
     '&bottom_margin=0.25' +           //All four margins must be set!
     '&left_margin=0.25' +             //All four margins must be set!
     '&right_margin=0.25' +            //All four margins must be set!
     '&sheetnames=false&printtitle=false' + // hide optional headers and footers
     '&pagenumbers=false&gridlines=false' + // hide page numbers and gridlines
     '&fzr=false' + // do not repeat row headers (frozen rows) on each page
     '&gid=2051090571' + // the sheet's Id. Change it to your sheet ID.
     // Here is the part for selecting range to export to PDF
     '&ir=false' +  //seems to be always false
     '&ic=false' +  //same as ic
     '&r1=0' +      //Start Row number - 1, so row 1 would be 0 , row 15 wold be 14
     '&c1=0' +      //Start Column number - 1, so column 1 would be 0, column 8 would be 7
     '&r2=37' +     //End Row number
     '&c2=10';       //End Column number

  var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};

  var response = UrlFetchApp.fetch(url+exportOptions, params).getBlob();

    GmailApp.sendEmail(email, subject, body, {
      htmlBody: body,
      cc: ccemail,
      attachments: [{
            fileName: "Corporate Year-End Checklist." + company + ".pdf",
            content: response.getBytes(),
            mimeType: "application/pdf"
        },
        files
        ]
    });
}

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

Body:
What I'm trying to do is onSubmit script in google sheets from a submitted google forms include the uploaded PDFs from google form submittion and area of spreadsheet with some of the conolidated data

I dont know how to combine the url lists from the google form submission where a single cell may contain multile URLs to upload PDF or none at all

function myFunction() {
  DocumentApp.getActiveDocument();
  DriveApp.getFiles();

  const ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1ELQ-SvRwWRmqDae1xz_-062oIs5RrzsQzYs7zFrCdxk/edit");
  var ss_formUrl = SpreadsheetApp.getActiveSpreadsheet().getFormUrl;
  var ss_dynamic = SpreadsheetApp.getActiveSheet().getSheetId();
  var ccemail = 'bruno.brottes@gmail.com';
  var email = ss.getSheetByName("DATA").getRange("E1").getValue().toString();
  var company = ss.getSheetByName("DATA").getRange("B1").getValue().toString();
  var attachments1 = ss.getSheetByName("DATA").getRange("J1").getValue().toString();
  //MIMETYPE:PDF
  //drive.google.com/open?id=1IpuzbJO3LnSV80iAr6OZ-jSrn5ht7uYT
  var attachments2 = ss.getSheetByName("DATA").getRange("P1").getValue().toString();
  //MIMETYPE:PDF
  //drive.google.com/open?id=1IpuzbJO3LnSV80iAr6OZ-jSrn5ht7uYT
  var attachments3 = ss.getSheetByName("DATA").getRange("V1").getValue().toString();
  //MIMETYPE:PDF
  //drive.google.com/open?id=1lSnyBdfPFWvxVRedZo_SgK6HTLoTfFuA,
  //drive.google.com/open?id=19g8oKib4sSvEVHDAO4IGd1hhJsJ-jY_A,
  //drive.google.com/open?id=1WxOJCD0STFLOQ4Lw0Mw4ZOAQ3OVUx9-k
  var attachments4 = ss.getSheetByName("DATA").getRange("AQ1").getValue().toString();
  //MINETYPE:PDF
  //drive.google.com/open?id=116ijk7n_CdmKWS6Z_aN0IlKJ1vNoeY7I
  var attachments5 = ss.getSheetByName('DATA').getRange('AS1').getValue().toString();
  //MINITYPE:ZIP
  var combinedAttachments = ['attachments1','attachments2','attachments3','attachments4','attachments5'];
  var combinedAll = ss_dynamic.getRange(combinedAttachments);
  var combinedAll = combinedAttachments1.concat(combinedAttachments2).concat(combinedAttachments3).concat(combinedAttachments4);

  for (var i = 0; i < combinedAll.length; i++)
  {
    var files = DriveApp.createFile(combinedAll[i]);
    attachments.push(files);
  }

      if(files){
        var files = files.split(', ');
      }

  const subject = 'Year-End.' + procedure + ".company" + ".pdf";

  const body = "See Attached";

  const url = 'https://docs.google.com/spreadsheets/d/1ELQ-SvRwWRmqDae1xz_-062oIs5RrzsQzYs7zFrCdxk/export?';

 const exportOptions =
     'exportFormat=pdf&format=pdf' + // export as pdf
     '&size=letter' + // paper size letter / You can use A4 or legal
     '&portrait=true' + // orientation portal, use false for landscape
     '&fitw=true' + // fit to page width false, to get the actual size
     '&fith=true' +
     '&top_margin=0.25' +              //All four margins must be set!
     '&bottom_margin=0.25' +           //All four margins must be set!
     '&left_margin=0.25' +             //All four margins must be set!
     '&right_margin=0.25' +            //All four margins must be set!
     '&sheetnames=false&printtitle=false' + // hide optional headers and footers
     '&pagenumbers=false&gridlines=false' + // hide page numbers and gridlines
     '&fzr=false' + // do not repeat row headers (frozen rows) on each page
     '&gid=2051090571' + // the sheet's Id. Change it to your sheet ID.
     // Here is the part for selecting range to export to PDF
     '&ir=false' +  //seems to be always false
     '&ic=false' +  //same as ic
     '&r1=0' +      //Start Row number - 1, so row 1 would be 0 , row 15 wold be 14
     '&c1=0' +      //Start Column number - 1, so column 1 would be 0, column 8 would be 7
     '&r2=37' +     //End Row number
     '&c2=10';       //End Column number

  var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};

  var response = UrlFetchApp.fetch(url+exportOptions, params).getBlob();

    GmailApp.sendEmail(email, subject, body, {
      htmlBody: body,
      cc: ccemail,
      attachments: [{
            fileName: "Corporate Year-End Checklist." + company + ".pdf",
            content: response.getBytes(),
            mimeType: "application/pdf"
        },
        files
        ]
    });
}


问:
Cross validation in SuperLearner: How to get results (R², RMSE, etc.) for each individual fold?
I am using SuperLearner for repeated V-fold or cross validation. Is there a way to obtain individual results for each of the say V=10 folds?

```<code># Packages
library(tidyverse)
library(SuperLearner)
library(caret)

# Some data
X <- matrix(rnorm(1000 * 50), nrow = 1000, ncol = 50)
Y <- X[, 1] + sqrt(abs(X[, 2] * X[, 3])) + X[, 2] - X[, 3] + rnorm(1000)
df <- cbind(Y, X) %>% as.data.frame()

# Cross validation in SuperLearner
model = CV.SuperLearner(Y = df$Y,
                        X = df %>% select(-Y),
                        family = gaussian(),
                        SL.library = c("SL.lm"),
                        V = 5)

# Look up folds
model$folds

# Look up individual results for each fold...?
</code>```

If you compare this to caret, it's pretty straight forward.

```<code># Cross validation in caret
train.control <- trainControl(method = "repeatedcv",
                              number = 5,
                              repeats = 5)

model <- train(Y ~ .,
               data = df,
               method = "lm",
               trControl = train.control,
               tuneLength = 10)

# Look up results
model$resample
</code>```

Long story short, where is the model$resample in SuperLearner?

Body:
I am using SuperLearner for repeated V-fold or cross validation. Is there a way to obtain individual results for each of the say V=10 folds?

# Packages
library(tidyverse)
library(SuperLearner)
library(caret)

# Some data
X <- matrix(rnorm(1000 * 50), nrow = 1000, ncol = 50)
Y <- X[, 1] + sqrt(abs(X[, 2] * X[, 3])) + X[, 2] - X[, 3] + rnorm(1000)
df <- cbind(Y, X) %>% as.data.frame()

# Cross validation in SuperLearner
model = CV.SuperLearner(Y = df$Y,
                        X = df %>% select(-Y),
                        family = gaussian(),
                        SL.library = c("SL.lm"),
                        V = 5)

# Look up folds
model$folds

# Look up individual results for each fold...?

If you compare this to caret, it's pretty straight forward.

# Cross validation in caret
train.control <- trainControl(method = "repeatedcv",
                              number = 5,
                              repeats = 5)

model <- train(Y ~ .,
               data = df,
               method = "lm",
               trControl = train.control,
               tuneLength = 10)

# Look up results
model$resample

Long story short, where is the model$resample in SuperLearner?


问:
Is it posible to use httponly cookie from api.domain.com in SPA from domain.com?

I have an SPA on domain.com.
I have an  API on  api.domain.com.

User from SPA sending request (with login and password) to API.
Everything fine - he gets httponly cookie for api.domain.com ans
JWTokens in respose body.

Strange we can update cookie for  api.domain.com from JS (from domain.com).

But then SPA makes anther request to API (api.domain.com/refresh), and
Chrome notes that cookie must have option SameSite (none), or cookies
will be omited! So we fail to refresh JWTs.

But if we do this (SameSite none), we can make another SPA2 on domain-bla-bla.com
and if user have already cookie for api.domain.com we can
make request to api.domain.com/refresh from this SPA2. And this is
rather kind of bad situation.

How we can split SPA to domain.com & API to the api.domain.com in secure
manner?

#1 I have some idea  So.

It wil be wounderful to have cookies for different pairs, for example:
UI on domain.com and API on api.domain.com - one cookie.
UI on api.domain.com and API on api.domain.com - another one cookie.
UI on domain-bla-bla.com and API on api.domain.com - another more cookie.

But cookies generates on api.domain.com.

Maybe I'm wrong, but I can get origin header on api.domain.com and make
cookies name like api_domain_com_cookie_name.
Than on cookie check I'll get origin header on api.domain.com and check
my cookie. api_domain_com_cookie_name.

But from another origin domain-bla-bla.com.
Ill will check it own cookie named: domain_bla_bla_com_cookie_name - and
it will be empty.

It looks like it will secure with option SameSite (none), will not it?

#2 Or just have list of posible origins.

Is one of this ideas is safe enough?

Is it posible to set origin header with some custom lib like axios (user have normal browser like Chrome or Firefox or IE)?

Sorry for blockqoutes, parser alerts that i have code in the message =\


问:
Check only a range of checkboxes
I have this code with works brilliantly for me. I just need a small alteration to be able to select a range of cells as well, meaning:

Either H15-H17 or H22 or H26 in the attached image.enter image description here

the code I have is the following:

```<code>var CHECKBOX_CELLS = ["H15", "H22", "H26"];

function onEdit(e) {
  var range = e.range;

  var checkboxIndex = CHECKBOX_CELLS.indexOf(range.getA1Notation());

  if (checkboxIndex > -1 && range.getValue() == true) {
    var sheet = range.getSheet();

    for (var i=0; i<CHECKBOX_CELLS.length; i++) {
      if (i==checkboxIndex) continue;

      sheet.getRange(CHECKBOX_CELLS[i]).setValue(false);
    }
  }
}
</code>```
```<code>
</code>```

Title: Check only a range of checkboxes

Body:
I have this code with works brilliantly for me. I just need a small alteration to be able to select a range of cells as well, meaning:

Either H15-H17 or H22 or H26 in the attached image.enter image description here

the code I have is the following:

var CHECKBOX_CELLS = ["H15", "H22", "H26"];

function onEdit(e) {
  var range = e.range;

  var checkboxIndex = CHECKBOX_CELLS.indexOf(range.getA1Notation());

  if (checkboxIndex > -1 && range.getValue() == true) {
    var sheet = range.getSheet();

    for (var i=0; i<CHECKBOX_CELLS.length; i++) {
      if (i==checkboxIndex) continue;

      sheet.getRange(CHECKBOX_CELLS[i]).setValue(false);
    }
  }
}


问:
Entity Framework Core - How to have join table of many to many automatically update each respective reference
Say I have a Person class with a property : List<Person>, called Friends. I want to have it so that adding a Person to the friend list of one class automatically adds it to the friend list of another Person.

According to documentation, to have a self-referencing many-to-many table you need to have two collections and EF will generate the join table PersonPerson.

```<code>public class Person
{
    public string Name //...
    public List<Person>? FriendOf { get; set; } = new();
    public List<Person>? FriendWith { get; set; } = new();
}

public class PersonPerson
{
     //EF will create shadow Ids for both
     public Person p1;

     public Person p2;
}
</code>```

I would like to do the following

```<code>person1 = new Person();
person2 = new Person();

person1.FriendsWith.Add(Person2));

</code>```

and have person 2 also have person 1 added to their respective Lists.  I wasn't sure if EF could do this automatically or if I have to create a function to make 4 assignments to achieve what I want.

I've created a static method that does something like this, but if I'm expanding my application this introduces a lot of extra complexity.

Body:
Say I have a Person class with a property : List<Person>, called Friends. I want to have it so that adding a Person to the friend list of one class automatically adds it to the friend list of another Person.

According to documentation, to have a self-referencing many-to-many table you need to have two collections and EF will generate the join table PersonPerson.

public class Person
{
    public string Name //...
    public List<Person>? FriendOf { get; set; } = new();
    public List<Person>? FriendWith { get; set; } = new();
}

public class PersonPerson
{
     //EF will create shadow Ids for both
     public Person p1;

     public Person p2;
}

I would like to do the following

person1 = new Person();
person2 = new Person();

person1.FriendsWith.Add(Person2));

and have person 2 also have person 1 added to their respective Lists.  I wasn't sure if EF could do this automatically or if I have to create a function to make 4 assignments to achieve what I want.

I've created a static method that does something like this, but if I'm expanding my application this introduces a lot of extra complexity.