Nesting React Native Expo Scrollview One for vertical and on for horizontal not working as expected

I am trying to create two React Native Views one which scrolls vertically and one inside that one which scrolls a svg d3 graph horizontally. For the inner horizontal scrolling I am seeing a graph which is cut short horizonatlly and is not scrollable. Here is my code:

<ScrollView style={styles.scrollView}>
    {graphLoaded &&
        {loadingIcon &&
            <ActivityIndicator size="large" />
          }
        <ScrollView style={styles.healthSpanGraph} horizontal={true} >
            <Svg id="graphLandingPage" width='0%' height='0%'>
            </Svg>
        </ScrollView>
        <DataTable style={styles.container}>
        <DataTable.Header style={styles.tableHeader}>
          <DataTable.Title style={styles.tableColumn}>Disease Name</DataTable.Title>
          <DataTable.Title style={styles.tableColumn}>Action</DataTable.Title>
          <DataTable.Title style={styles.tableColumn}>Action</DataTable.Title>
          <DataTable.Title style={styles.tableColumn}>View</DataTable.Title>
        </DataTable.Header>
            {graphs.slice(
                page * numberOfItemsPerPage,
                page * numberOfItemsPerPage + numberOfItemsPerPage
              ).map((item) => (
                <DataTable.Row key={item.id} style={selectedGraphs[item.id]?[styles.tableRow, styles.tableSelectedColor]:styles.tableRow} onPress={()=>highlightGraph(item.id)}>
                  <DataTable.Cell style={styles.tableColumn}>{item.diseaseName}</DataTable.Cell>
                   <DataTable.Cell style={styles.tableColumn} numeric>
                      <TouchableOpacity onPress={() => navigation.navigate("UpdateUserGraphWeb",
                      { id: item.id, diseaseId: item.userDiseaseId, diseaseName: item.diseaseName, userId: item.userId})}>
                          <Text style={styles.actionText}>Update Graph</Text>
                        </TouchableOpacity>
                  </DataTable.Cell>
                  <DataTable.Cell style={styles.tableColumn} numeric>
                        <TouchableOpacity onPress={() => navigation.navigate("DeleteUserGraphModalWeb", { id: item.id})}>
                            <Text style={styles.actionText}>Delete Graph</Text>
                          </TouchableOpacity>
                    </DataTable.Cell>
                    <DataTable.Cell style={styles.tableColumn} numeric>
                            <TouchableOpacity onPress={() => navigation.navigate("PatientGraphLandingPageWeb", { id: item.id})}>
                                <Text style={styles.actionText}>View Graph</Text>
                              </TouchableOpacity>
                        </DataTable.Cell>
                </DataTable.Row>
              ))}
              <DataTable.Pagination
                 page={page}
                 numberOfPages={Math.ceil(graphs.length / numberOfItemsPerPage)}
                 onPageChange={(page) => changePage(page)}
                 label={`${from + 1}-${to} of ${graphs.length}`}
                 showFastPaginationControls
                 numberOfItemsPerPage={numberOfItemsPerPage}
               />
      </DataTable>
    </ScrollView>

And my stylings:

container: {
    flex: 1,
    flexDirection:'column',
    backgroundColor: 'white',
    alignItems: "center",
    justifyContent: "center",
  },
    scrollView: {
        marginHorizontal: 0,
        height: 500,
    },
    healthSpanGraph: {
        marginHorizontal: 0,
        width: wp(100)
    },
 tableHeader: {
    backgroundColor: '#2196F3',
    color: 'black',
    width: Platform.OS === 'web' ? wp(100) : wp(80),
    marginTop: (isSafari === true || iOSSafari === true) ? 70 : 0
  },
  tableRow: {
    backgroundColor: 'white',
    color: 'black',
    width: Platform.OS === 'web' ? wp(100) : wp(80)
  }

If I remove the inner ScrollView The graph appears as normal but with it the graph appears cropped horizontally.

add multiple blazor components to dependency injection

Pretty new to Blazor and asp.net core as well.

I am reading through asp.net documentation dependency injection.

I am able to register an initial component MyCounter.razor file and import it into my ui framework.

   app.MapRazorComponents<Prodigy.Dashboards.Components.Chart>()
   .AddInteractiveServerRenderMode();
   app.MapRazorComponents<Prodigy.Dashboards.Components.Counter>()
   .AddInteractiveServerRenderMode();```


```services.AddServerSideBlazor(options =>
{
   options.RootComponents.RegisterCustomElement<Counter>("my-counter");
   options.RootComponents.RegisterCustomElement<Chart>("my-chart");
});```

I have the ability to see counter in as 

<my-counter></my-counter>

When i go to use 

```<my-chart></my-chart>```
// That is unavailable and errors out in vscode and chrome.  

I haven't found all of the documentation on blazor to this point that.  But what i am trying to figure out if this is limited to one razor component or if this is something that i can add multiple components to? 


I am looking for access to both **Chart** and **Counter** componets.  But I want to use them separately not looking to have a parent child relationship with them.  

Regex for Equations Coefficient

I have three equations in JavaScript with three unknowns “u1, u2 & u3”. I am solving the equations for the unknowns using Scipy Python.

The equations are in string format created with Algebrite library. My initial try was to create a Python script to capture JS output(string) and convert it to Python equations. It has worked but someone suggested to export the coefficients of u1, u2 & u3 and create a general equation in python to include these coefficients.

The equations are:

Equation 1: 17310.121449…+512.680632…u1+991.680290…u2+187.095064…u3+13.796783…u1^2.0+16.565u2^2.0-2.784782u3^2.0-4.257205…u1u2-0.308802u1u3

Equation 2: -24410.730595…-595.39432u1-1259.885584…u2-13.581724u3-20.751731u1^2.0-17.949u2^2.0+2.784782u3^2.0+5.327867u1u2+5.48054u2u3

Equation 3: 1539.663-22.822u2-16.484u3+3.377u2^2+3.38u3^2-10.365*(491590.877+1730.043u1+4553.564u2-22926.856u3+15.341u1^2+43.182u2^2+267.321u3^2-1356.45u1u2+27.428u1u2u3-0.149u1u2u3^2-1419.688u1u3-4.692u1u2^2-0.144u1u2^2u3+32.19u1u3^2-40.282u2u3-1.542u2u3^2-1.361u1^2u2+1.956u1^2u2u3-2.562u1^2u3+0.983u1^2u2^2+0.998u1^2u3^2-1.576u2^2u3+0.03u2^2u3^2)^0.5+6.652u2u3

I tried using the following Regex expressions:
Regex used for the three equations are:
const regex1 = /([+-]?d+(.d+)?)(?=*u1(?:^2.0)?|*u2(?:^2.0)?|*u3(?:^2.0)?|*u1*u2|*u1*u3)/g;

const regex2 = /([+-]?d+(.d+)?)(?=*u1(?:^2.0)?|*u2(?:^2.0)?|*u3(?:^2.0)?|*u1*u2|*u2*u3)|^[+-]?d+(.d+)?(?!*u)/g;

const regex3 = /([+-]?d+(.d+)?)(?=*u1(?:^2.0)?|*u2(?:^2.0)?|*u3(?:^2.0)?|*u1*u2|*u2*u3|*u1*u2*u3|*u1*u2*u3^2|*u1*u3|*u2*u3)|^[+-]?d+(.d+)?(?!*u)|(?<=()[+-]?d+(.d+)?/g;

The result contains some of the coefficients but it contains a lot of 1 & 2. I assume that it is because it cannot understand when there are compound coefficients like u1, u2 & u3 together in the expression like u2u3 or u1u2*u3.

An example result for equation 3 is as follows:
Equation 3 Coefficients: [
1539.663, -22.822, -16.484, 3.377,
3.38, 491590.877, 1730.043, 4553.564,
-22926.856, 15.341, 43.182, 267.321,
-1356.45, 1, 27.428, 1,
2, -0.149, 1, 2,
-1419.688, 1, -4.692, 1,
-0.144, 1, 2, 32.19,
1, -40.282, 2, -1.542,
2, -1.361, 2, 1.956,
2, 2, -2.562, 2,
0.983, 2, 0.998, 2,
-1.576, 2, 0.03, 2,
6.652, 2

I was not expecting the 1’s and 2’s.

Angular router redirects immediately

I have a route config:

{
    path: 'dashboard',
    component: UserDashboardPageComponent,
    title: 'Panel',
    children: [
      {
        path: 'summary',
        component: DashboardSummaryComponent,
        title: 'Podsumowanie',
      },
      {
        path: 'official-exams',
        component: OfficialMaturaExamsComponent,
        title: 'Arkusze maturalne',
      },
      {
        path: 'mock-exams',
        component: MockMaturaExamsComponent,
        title: 'Próbne matury',
      },
      {
        path: 'exams-exercises',
        component: MaturaExamsExcercisesComponent,
        title: 'Zadania maturalne',
      }...

and then i have a page with router outlet:

<section class="flex h-[100vh]">
  <app-dashboard-navigation class="min-w-[20rem]"></app-dashboard-navigation>
  <router-outlet></router-outlet>
</section>

to navigate i have a card:

<div
  class="flex gap-5 justify-left items-center text-center pl-5 group hover:cursor-pointer m-3 backdrop-blur-md"
  [routerLink]="route"
>
  <ng-icon
    class="text-3xl group-hover:text-cyan-600 transition-all duration-300"
    [name]="icon"
  ></ng-icon>
  <p
    class="text-xl font-bold group-hover:text-cyan-600 transition-all duration-300"
  >
    {{ title }}
  </p>
</div>

and then:

@for(opt of menu; track opt){
    <app-dashboard-nav-card
      [icon]="opt.icon"
      [title]="opt.title"
      [route]="opt.route"
    ></app-dashboard-nav-card>
    }

from the list of items:

  menu: any[] = [
    {
      icon: 'tablerAtom',
      title: 'Arkusze maturalne',
      route: 'official-exams',
    },
    {
      icon: 'tablerPaperclip',
      title: 'Arkusze próbne',
      route: 'mock-exams',
    },
    {
      icon: 'tablerNotebook',
      title: 'Zadania maturalne',
      route: 'exams-exercises',
    },
  ];

The problem is that when i enter the official-exams (dashboard/official-exams) through the navbar, i get immediately redirected to the ‘dashboard‘ and i have to use browser built in go back to access the resource. I can manually enter the url and it works fine, but when i try to enter any component that should be inside router-outlet i get immediately redirected to dashboard.

I get no error the url is bad, and after all i can go back to right url. The urls are good, but i get redirected all the time.

Why? How to fix it?

Python Mako: JS not working in rendered html

I have got the following folder structure

daemon.py  
template.mako  
html/  
  main.html  
  javascript/  
    script.js

Now my daemon is running a wsgi server, using bottle. The endpoint does the following:

@route("/main")
def main():
    lookup = TemplateLookup(directories=["html", "html/javascript"])

    return Template(filename="template.mako", lookup=lookup).render()

The mako template now includes the main.html (which contains the header) and does some looped function execution, rendering a card item from bulma for each turn of the loop. A button is supposed to be expanding the card via the script.js. The latter in turn is included via <script type="text/javascript" src="javascript/script.js"></script>.

I’ve tried many different ways of providing the right path in src and also moving the <script> element from main.html to template.mako. The site itself is rendering just fine, correctly including the header. But besides the 200 for the site itself, I always get a 404 for the script upon loading the page.

Does anyone have an idea, what I am doing wrong?

d3.js (v7) – Zoom behaviour & performance

The following code is an example of a chart that combines manual zooming triggered by drag/wheel/click and automatic zooming executed by the function “zoomToArea”. The current behavior is quite satisfactory, but the zoom state update remains independent for each zoom source. I’m trying to store the zoom.transform state in a “zoomTransform” variable, but I haven’t managed to override the state to avoid resetting the zoom when resuming the wheel interaction.

My questions:

  • How can I ensure that the current zoom position is uniquely stored for both triggers?

  • I couldn’t integrate the new “scaleTo” and “translateTo” functions into a single transition. The “zoomToArea” function needs to be improved, actually it doesn’t work properly from any starting point, I temporarly added “zoomHomeInstant” to ensure the right position is targetted.

  • (BONUS: Performance) Some datasets can be generated. In cases with a large amount of data, rendering slows down in the “renderChart” function. Is this global re-draw on zoom correct? If you have any structural improvement suggestions to optimize performance, I’d love to hear them!

<div>
  <button id="zoom_to_home">Reset Zoom</button>
  <button id="zoom1">Zoom1</button>
  <button id="zoom2">Zoom2</button>
  <button id="zoom3">Zoom3</button>
  <button id="zoom4">Zoom4</button>
</div>
<div>
  <button id="small_data_btn">Load small data</button>
  <button id="medium_data_btn">Load medium data</button>
  <button id="large_data_btn">Load large data</button>
</div>
<div id="chart_canvas_ctn"></div>

// DIMENSIONS

const outerWidth = 500
const outerHeight = 500
const margin = { top: 50, right: 50, bottom: 50, left: 50 }
const width = outerWidth - margin.left - margin.right
const height = outerHeight - margin.top - margin.bottom

// CREATE SVG CTN

var SVG = d3
  .select("#chart_canvas_ctn")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")")

// CLIP PATH

var clipPath = SVG.append("defs")
  .append("SVG:clipPath")
  .attr("id", "clip")
  .append("SVG:rect")
  .attr("x", 0)
  .attr("y", 0)
  .attr("width", width)
  .attr("height", height)

// SCALES

var x = d3.scaleLinear().domain([0, 400]).range([0, width])

var y = d3.scaleLinear().domain([0, 400]).range([height, 0])

// GRIDS

var xGrid = SVG.append("g")
xGrid
  .selectAll(".x-line")
  .attr("clip-path", "url(#clip)")
  .data(d3.range(0, 400, 100))
  .enter()
  .append("line")
  .attr("class", "grid")
  .attr("x1", (d) => x(d))
  .attr("x2", (d) => x(d))
  .attr("y1", 0)
  .attr("y2", height)
  .attr("stroke", "#ccc")
  .attr("stroke-width", 1)

var yGrid = SVG.append("g")
yGrid
  .selectAll(".y-line")
  .attr("clip-path", "url(#clip)")
  .data(d3.range(0, 400, 100))
  .enter()
  .append("line")
  .attr("class", "grid")
  .attr("x1", 0)
  .attr("x2", width)
  .attr("y1", (d) => y(d))
  .attr("y2", (d) => y(d))
  .attr("stroke", "#ccc")
  .attr("stroke-width", 1)

// AXIS

var xAxisBot = SVG.append("g")
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(x))

var yAxisLeft = SVG.append("g")
  .attr("transform", "translate(0,0)")
  .call(d3.axisLeft(y))

// ZOOM

// to store zoom last state before change
let zoomTransform = d3.zoomIdentity

var zoom = d3
  .zoom()
  .scaleExtent([1, 100])
  .translateExtent([
    [0, 0],
    [width, height],
  ])
  .extent([
    [0, 0],
    [width, height],
  ])
  .interpolate(d3.interpolate)

  .on("start", function (event) {})
  .on("end", function (event) {})
  .on("zoom", function (event) {
    renderChart(event.transform)
  })

SVG.append("rect")
  .attr("width", width)
  .attr("height", height)
  .style("fill", "none")
  .style("pointer-events", "all")
  .call(zoom)

// INIT RECTANGLES

const size_rect = 1.26
var squares = SVG.append("g")

// RESIZE

function renderChart(transform) {
  var prevTransform = zoomTransform
  var zoomFactor = transform.k

  // NEW SCALE

  var newX = transform.rescaleX(x)
  var newY = transform.rescaleY(y)

  // AXIS

  xAxisBot.call(d3.axisBottom(newX))
  yAxisLeft.call(d3.axisLeft(newY))

  // GRID

  xGrid
    .selectAll("line")
    .attr("clip-path", "url(#clip)")
    .attr("x1", (d) => transform.applyX(x(d)))
    .attr("x2", (d) => transform.applyX(x(d)))

  yGrid
    .selectAll("line")
    .attr("clip-path", "url(#clip)")
    .attr("y1", (d) => transform.applyY(y(d)))
    .attr("y2", (d) => transform.applyY(y(d)))

  // ELEMENTS

  squares
    .selectAll("rect")
    .attr("clip-path", "url(#clip)")
    .attr("x", function (d) {
      return newX(d.x) - (size_rect / 2) * zoomFactor
    })
    .attr("y", function (d) {
      return newY(d.y) - (size_rect / 2) * zoomFactor
    })
    .attr("width", size_rect * zoomFactor)
    .attr("height", size_rect * zoomFactor)

  // -

  zoomTransform = transform
}

// AUTO ZOOM

document.getElementById("zoom_to_home").addEventListener("click", function (e) {
  SVG.transition()
    .duration(2000)
    .call(zoom.transform, d3.zoomIdentity)
    .on("end", function () {
      console.log("Zoom réinitialisé")
    })
})

function zoomHomeInstant() {
  SVG.call(zoom.transform, d3.zoomIdentity).on("end", function () {
    console.log("Zoom réinitialisé")
  })
}

document.getElementById("zoom1").addEventListener("click", function (e) {
  zoomToArea(0, 0, 300, 300)
})
document.getElementById("zoom2").addEventListener("click", function (e) {
  zoomToArea(75, 75, 125, 125)
})
document.getElementById("zoom3").addEventListener("click", function (e) {
  zoomToArea(90, 190, 210, 310)
})

document.getElementById("zoom4").addEventListener("click", function (e) {
  SVG.transition()
    .duration(1000)
    .call(zoom.scaleTo, 4)
    .on("end", function () {
      console.log("Zoom 4 OK")
    })
})

function zoomToArea(x1, y1, x2, y2) {
  console.log("=============")
  zoomHomeInstant()

  // Récupérer la transformation actuelle du zoom
  var currTransform = d3.zoomTransform(SVG.node())
  console.log("currTransform", currTransform)
  var storedTransform = zoomTransform
  console.log("storedTransform", storedTransform)

  // Récupérer les dimensions visibles du SVG
  var rectBBox = SVG.select("rect").node().getBBox()
  var rectWidth = rectBBox.width
  var rectHeight = rectBBox.height

  console.log("rect dimensions:", { rectWidth, rectHeight })

  var scaledX1 = x(x1)
  var scaledY1 = y(y1)
  var scaledX2 = x(x2)
  var scaledY2 = y(y2)

  var appliedX1 = currTransform.applyX(x(x1))
  var appliedY1 = currTransform.applyY(y(y1))
  var appliedX2 = currTransform.applyX(x(x2))
  var appliedY2 = currTransform.applyY(y(y2))

  console.log("raw", { x1: x1, y1: y1, x2: x2, y2: y2 })
  console.log("scaled", {
    x1: scaledX1,
    y1: scaledY1,
    x2: scaledX2,
    y2: scaledY2,
  })
  console.log("applied", {
    x1: appliedX1,
    y1: appliedY1,
    x2: appliedX2,
    y2: appliedY2,
  })

  // Calculer les dimensions de la zone cible
  var targetWidth = Math.abs(appliedX2 - appliedX1)
  var targetHeight = Math.abs(appliedY2 - appliedY1)

  console.log("Target area dimensions:", { targetWidth, targetHeight })

  // Calculer le scale automatiquement (min pour conserver les proportions)
  var scaleX = rectWidth / targetWidth
  var scaleY = rectHeight / targetHeight
  var targetScale = Math.min(scaleX, scaleY)

  console.log("Calculated scale:", { scaleX, scaleY, targetScale })

  // Calculer les coordonnées du centre de la zone cible
  var centerX = (appliedX1 + appliedX2) / 2 - currTransform.x
  var centerY = (appliedY1 + appliedY2) / 2 - currTransform.y

  console.log("Center of target area:", { centerX, centerY })

  // Appliquer la transformation
  SVG.transition()
    .duration(1000)
    .ease(d3.easeQuad) // d3.easeCubicInOut ou d3.easeQuad, d3.easeCircle
    .call(
      zoom.transform,
      currTransform
        .translate(rectWidth / 2, rectHeight / 2) // Translation pour centrer
        .scale(targetScale / currTransform.k) // Zoom calculé
        .translate(-centerX, -centerY), // Recentrer sur la zone cible
    )
}

// LOAD DATA

var data = []

document
  .getElementById("small_data_btn")
  .addEventListener("click", function (e) {
    generateRandomData(500)
  })

document
  .getElementById("medium_data_btn")
  .addEventListener("click", function (e) {
    generateRandomData(5000)
  })

document
  .getElementById("large_data_btn")
  .addEventListener("click", function (e) {
    generateRandomData(25000)
  })

function generateRandomData(count) {
  data = []
  for ($i = 0; $i < count; $i++) {
    data.push({
      id: generateRandomIntBetween(1000, 9999),
      x: generateRandomIntBetween(x.domain()[0], x.domain()[1]),
      y: generateRandomIntBetween(y.domain()[0], y.domain()[1]),
      color: generateRandomColorHex(),
    })
  }
  refreshData()
}

function refreshData() {
  // console.log('data',data)

  squares.selectAll("rect").remove()
  squares
    .selectAll("rect")
    .data(data)
    .enter()
    .append("rect")
    // .attr("x", function (d) { return x(d.x)-size_rect/2;})
    // .attr("y", function (d) { return y(d.y)-size_rect/2;})
    // .attr("width", size_rect)
    // .attr("height", size_rect)
    .attr("fill", function (d) {
      return d.color
    })

  renderChart(zoomTransform)
}

function generateRandomIntBetween(a, b) {
  if (a > b) [a, b] = [b, a]
  a = Math.ceil(a)
  b = Math.floor(b)
  return Math.floor(Math.random() * (b - a + 1)) + a
}

function generateRandomColorHex() {
  return `#${Math.floor(Math.random() * 16777215).toString(16)}`
}

Best way to add dynamic features into an html website without a CMS or php?

I’m in charge of a large-ish company website that’s built entirely on .html/css and is likely going to stay that way for a while. I’d love to build in some dynamic functionality in the following ways…

1.) Four of our pages have a “Featured Reports” section that show the three most recent reports we’ve published along with a synopsis. It would be great if this could be drawn from a master list.

2.) Similarly those four pages each link to a page that has the full list of every report published within that category. If possible I’d like to populate this page from the same master list.

The idea is that the master list, either one for all four categories or four lists, can be updated, either in html or plain or rich text and both the featured reports and full reports sections can be updated automatically. Is this something I can do with xml? Is there another option? I’m looking to avoid using a CMS or any sort of database- just a list that’s manually updated periodically.

Classic ASP retrieving Unique values from a check box

Currently i have 4 items with a number of parts linked to a itemkeyid (makes it unique in the job) my issue is that when trying to extract the aperturekeyid its either taking all apertures on the job (not just the selected item within the job) or not displaying anything at all.

my target is to get the array to only show me the unique apertureKeyIDs assigned to the Itemkeyid so i can then next SQL Update statements as it generates a record

Im using the developer tool in google to see my pay load and Get_APKEY_ is missing.
been at this for hourrrrsss.
in advance thank you so much to anyone that can assist and educate me with this

Current code consist of this:

function toggleHiddenField(checkbox, hiddenFieldId) {
        var hiddenField = document.getElementById(hiddenFieldId);
        if (checkbox.checked) {
            hiddenField.disabled = false;
            console.log('Enabled hidden field:', hiddenFieldId);
        } else {
            hiddenField.disabled = true;
            console.log('Disabled hidden field:', hiddenFieldId);
        }
    }

Classic asp:

                        .write "<INPUT type=checkbox id=chkSection_" & strEntity & "_" & strSectionID & " name=chkSection_" & lngItemKeyID & "_" & trim(rsRemake("ApRef")) & " value=" & strSectionID 
                        .write " style=" & chr(34) & "width:15px" & chr(34) & " onclick=""toggleHiddenField(this, 'Get_APKEY_" & lngItemKeyID & "')"" >"

                        .write "<INPUT type=hidden id=Get_APKEY_" & lngItemKeyID & " name=Get_APKEY_" & lngItemKeyID & " value=""" & trim(rsRemake("ApertureKeyID")) & """ disabled>" & vbCrLf

server side (classic asp still):

        Set lngApertureKeyID = Server.CreateObject("Scripting.Dictionary")

        ' Loop through form fields
        For Each itm In Request.Form
            If InStr(UCase(itm), "GET_APKEY") > 0 Then
                ' Extract the ApertureKeyID value from the form field
                Dim apertureKeyID
                apertureKeyID = Trim(Request.Form(itm))

                ' Add to the dictionary if it is not already present (ensures uniqueness)
                If Not lngApertureKeyID.Exists(apertureKeyID) Then
                    lngApertureKeyID.Add apertureKeyID, Nothing
                End If

                ' Debugging: Print out the form field and its value
                Response.Write itm & ": " & apertureKeyID & "<br>"
            End If
        Next

        ' Transfer the unique values to an array
        Dim uniqueApertureKeys()
        Dim index
        index = 0
        ReDim uniqueApertureKeys(lngApertureKeyID.Count - 1)

        ' Populate the array with the unique ApertureKeyIDs
        For Each strApertureKey In lngApertureKeyID.Keys
            uniqueApertureKeys(index) = strApertureKey
            index = index + 1
        Next

        ' Debugging: Output the unique ApertureKeyIDs for verification
        For i = 0 To UBound(uniqueApertureKeys)
            Response.Write "Unique ApertureKeyID: " & uniqueApertureKeys(i) & "<br>"
        Next

        ' Loop through the entire form and print all fields and their values
        For Each itm In Request.Form
            Response.Write itm & ": " & Request.Form(itm) & "<br>"
        Next

Expo (React Native) app not receiving the context from the AuthProvider

I have this problem with my expo app I’m actually a beginner to mobile app development as a whole, I’ve tried everything i can, but nothing worked.

I’m using TypeScript btw.

AuthContext.tsx:

import React, {
  createContext,
  useContext,
  useEffect,
  useState,
  ReactNode,
} from "react";
import axios from "axios";
import * as SecureStore from "expo-secure-store";
import { ActivityIndicator } from "react-native-paper";
import { jwtDecode } from "jwt-decode";

type AuthContextType = {
  onRegister: (username: string, password: string) => Promise<any>;
  onLogin: (username: string, password: string) => Promise<any>;
  onLogout: () => Promise<void>;
  authState: AuthStateType;
  authData: AuthDataType;
};

type AuthStateType = {
  token: string | null;
  authenticated: boolean;
};

type AuthDataType = {
  id: number | null;
  username: string | null;
  iat: number | null;
  exp: number | null;
};

const AuthContext = createContext<AuthContextType | undefined>(undefined);

const TOKEN_KEY = "authToken";
const API_URL = "https://anonytext-backend.vercel.app/api";

const useAuth = (): AuthContextType => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error("useAuth must be used within an AuthProvider");
  }
  return context;
};

type AuthProviderProps = {
  children: ReactNode;
};

const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
  const [loading, setLoading] = useState<boolean>(true);
  const [authState, setAuthState] = useState<AuthStateType>({
    token: null,
    authenticated: false,
  });
  const [authData, setAuthData] = useState<AuthDataType>({
    id: null,
    username: null,
    iat: null,
    exp: null,
  });

  const register = async (username: string, password: string): Promise<any> => {
    try {
      return await axios.post(`${API_URL}/auth/register`, {
        username,
        password,
      });
    } catch (e: any) {
      return {
        error: true,
        message: e.response?.data?.message || "An error occurred",
      };
    }
  };

  const login = async (username: string, password: string): Promise<any> => {
    try {
      const result = await axios.post(`${API_URL}/auth/login`, {
        username,
        password,
      });
      setAuthState({ token: result.data.access, authenticated: true });
      axios.defaults.headers.common[
        "Authorization"
      ] = `Bearer ${result.data.access}`;
      await SecureStore.setItemAsync(TOKEN_KEY, result.data.access);

      return result;
    } catch (e: any) {
      return {
        error: true,
        message: e.response?.data?.message || "An error occurred",
      };
    }
  };

  const logout = async (): Promise<void> => {
    await SecureStore.deleteItemAsync(TOKEN_KEY);
    axios.defaults.headers.common["Authorization"] = "";
    setAuthState({ token: null, authenticated: false });
  };

  useEffect(() => {
    const loadToken = async () => {
      const token = await SecureStore.getItemAsync(TOKEN_KEY);

      if (token) {
        axios.defaults.headers.common["Authorization"] = `Bearer ${token}`;
        setAuthState({ token, authenticated: true });
        setAuthData(jwtDecode(token));
      }
      setLoading(false);
    };

    loadToken();
  }, []);

  const contextData: AuthContextType = {
    onRegister: register,
    onLogin: login,
    onLogout: logout,
    authState,
    authData,
  };

  return (
    <AuthContext.Provider value={contextData}>
      {!loading ? children : <ActivityIndicator size={20} />}
    </AuthContext.Provider>
  );
};

export { AuthProvider, useAuth };

Which looks pretty solid to me and should be working, but i keep getting

(NOBRIDGE) ERROR  Warning: Error: useAuth must be used within an AuthProvider

This error is located at:
    in RootLayout
    in Unknown (created by Route())
    in Suspense (created by Route())
    in Route (created by Route())
    in Route() (created by ContextNavigator)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by wrapper)
    in wrapper (created by ContextNavigator)
    in ThemeProvider
    in EnsureSingleNavigator
    in BaseNavigationContainer
    in NavigationContainerInner (created by ContextNavigator)
    in ContextNavigator (created by ExpoRoot)
    in ExpoRoot (created by App)
    in App (created by ErrorOverlay)
    in ErrorToastContainer (created by ErrorOverlay)
    in ErrorOverlay (created by withDevTools(ErrorOverlay))
    in withDevTools(ErrorOverlay)
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
    in main(RootComponent)

According to this message, the useAuth hook is supposed to be used in a child element wrapped with the AuthProvider Context, which is exactly what i did here:

App.tsx:

import React from "react";
import { AuthProvider } from "@/context/AuthContext";
import RootLayout from "./app/_layout";
import { NotifierWrapper } from "react-native-notifier";
import { GestureHandlerRootView } from "react-native-gesture-handler";

// Wrap the entire app with AuthProvider
export default function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <NotifierWrapper>
        <AuthProvider>
          <RootLayout />
        </AuthProvider>
      </NotifierWrapper>
    </GestureHandlerRootView>
  );
}

And the ./app/_layout.tsx:

import React, { useCallback } from "react";
import { Slot, Redirect } from "expo-router";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { useFonts } from "expo-font";
import * as SplashScreen from "expo-splash-screen";
import { useAuth } from "@/context/AuthContext";
import { ActivityIndicator } from "react-native-paper";

// Prevent the splash screen from hiding until the font is loaded
SplashScreen.preventAutoHideAsync();

export default function RootLayout() {
  const { authState } = useAuth(); // Directly access authState from context

  console.log("Auth Context State:", authState);

  const [fontsLoaded] = useFonts({
    FontAwesome6Pro: require("../assets/fonts/fa-regular-400.ttf"),
    FontAwesome6ProLight: require("../assets/fonts/fa-light-300.ttf"),
    FontAwesome6ProSolid: require("../assets/fonts/fa-solid-900.ttf"),
  });

  const onLayoutRootView = useCallback(async () => {
    if (fontsLoaded) {
      await SplashScreen.hideAsync();
    }
  }, [fontsLoaded]);

  if (!fontsLoaded) {
    return null; // Keep splash screen visible while loading fonts
  }

  // If authState is undefined, don't attempt to render protected routes yet
  if (authState === undefined) {
    return <ActivityIndicator size={20} />; // Show loading indicator if auth state is undefined
  }

  return (
    <GestureHandlerRootView style={{ flex: 1 }} onLayout={onLayoutRootView}>
      {authState.authenticated ? <Slot /> : <Redirect href="/login" />}
    </GestureHandlerRootView>
  );
}

Which should also work cause i wrapped the RootLayout with the AuthProvider.

Is there something i did wrong or there’s a step i missed?

My Bash output (echo[string]) is appending characters from a previous echo command and I can’t figure out why

It’s my first post so please bear with me…

I am currently trying to learn how to script via bash(MacOS). I wrote some code, on one line, for a simple count down timer:

i=0; echo -en "Enter timer length (seconds): "; read num; echo "Timer starting...now"; sleep 1; for i in $(seq $num 1); do echo -ne "$i second(s) remaining"\r; sleep 1; done; echo -e "33[34mTimer Finished33[0m";

The code works for the most part, but there’s something weird happening with the output.
Im expecting: > ‘Timer Finished’ at the very end of the process, however, I am instead getting: > ‘Timer Finishedmaining’.

I’m really at a loss here. Could someone share some insight, please…thanks in advance!

I’ve tried formatting the strings differently, changing the ‘echo’ -options, removing terminal escapes… still at a loss.

Tom-Select.js, selected option disappears when active, while the dir is RTL

I used Tom-Select to customize the default html select box, and it works fine, until I clicked on a selected element then all the selected elements disappeared.
I check the documentation for a solution but I found the same issue:

this is a link of a gif (I can’t upload it to stackoverflow I don’t know why): https://s7.gifyu.com/images/SJP16.gif

I investigate the element and found that the position being changed, but when I set the position to fixed it shows up but it not where it has to be or deform the its container

Why is my custom Sanity file input component not saving the uploaded PDF file?

I am trying to create a custom file upload component for Sanity Studio to upload PDF files and generate a preview of the first page using pdftoimg-js. The component displays the file name and a preview of the first page correctly, but when I try to publish the document, the file is not saved.

Here’s the code for my custom input component (PdfUpload), this is my custom component where I try to upload a PDF and later to generate also an image of the pdf:

import React, { useState, useEffect } from 'react';
import PdfToImg from 'pdftoimg-js/browser';
import { Text } from '@sanity/ui';
import { FiUpload } from 'react-icons/fi';

const PdfUpload: React.FC = () => {
  const [file, setFile] = useState<File | null>(null);
  const [firstImage, setFirstImage] = useState<string | null>(null);

  const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFile = event.target.files ? event.target.files[0] : null;

    // console.log('selectedFile ', selectedFile);

    if (selectedFile) {
      if (selectedFile.type === 'application/pdf') {
        // console.log('selectedFile is PDF');

        setFile(selectedFile);
      } else {
        // console.log('selectedFile is not PDF');

        setFile(null);
      }
    }
  };

  useEffect(() => {
    const loadImages = async () => {
      if (!file) return;

      try {
        const response = await fetch(URL.createObjectURL(file));
        const pdfBuffer = await response.arrayBuffer();
        const pdfImages = await PdfToImg(pdfBuffer);

        if (pdfImages.length > 0) {
          setFirstImage(pdfImages[0]);
        }
      } catch (error) {
        setFile(null);
      }
    };

    loadImages();
  }, [file]);

  console.log('firstImage ', firstImage);
  console.log('file ', file);

  return (
    <div>
      <div className="mb-2 flex items-center rounded-md border border-[#555c75]">
        <label htmlFor="pdf-upload-input" className="flex cursor-pointer items-center border-r border-[#555c75] px-4 py-2 text-white">
          <FiUpload className="mr-2" />
          <span>{file ? 'Change PDF' : 'Upload PDF'}</span>
        </label>

        <div className="flex-1 px-4 py-2 text-sm text-gray-600">{file ? <Text>{file.name}</Text> : <Text>No file selected</Text>}</div>
      </div>

      <input type="file" id="pdf-upload-input" accept=".pdf" onChange={handleFileChange} className="hidden" />

      {firstImage && (
        <div className="mt-4 border-2 border-white bg-slate-900">
          <img src={firstImage} alt="First page of PDF" width={300} height={450} className="mx-auto my-4 block rounded-md" />
        </div>
      )}
    </div>
  );
};

export default PdfUpload;

However, when I try to publish the document after uploading a file, the file and its reference are not saved in Sanity. If I replace my custom component with the default file input:

defineField({
  name: 'pdfFile',
  type: 'file',
  title: 'PDF File',
  description: 'Upload the PDF file for the annual report.',
  options: {
    accept: '.pdf',
  },
  validation: (Rule) => Rule.required(),
}),

this works just fine I can upload a pdf and then I can press publish to save the pdf:
enter image description here

custom:

 defineField({
      name: 'pdfFile',
      type: 'file',
      title: 'PDF File',
      description: 'Upload the PDF file for the annual report.',
      options: {
        accept: '.pdf',
      },
      validation: (Rule) => Rule.required(),
      components: {
        input: PdfUpload,
      },
    }),

but in my custom component as soon as I upload the pdf I generate a thumbnail and I want to save it so later I can fetch this from the FE and show the pdf and also the thumbnail of the pdf, here as you can see the publish button is not visible meaning that the reference to pdf is not being saved in sanity.

enter image description here

when I use this, to get page content, pdfFile and thumbnail come as null and I cant not display the pdf and it thumbnail.

 const query = groq`
    *[_type == 'about' && !(_id in path('drafts.**'))][0]{
      title,
      subtitle,
      annualReports[]->{
        _id,
        pdfTitle,
        pdfFile{
          asset->{
            url
          }
        },
        thumbnail{
          asset->{
            url
          }
        }
      }
    }
  `;

I am not sure what Iam doing wrong but I think somehow PdfUpload is not working properly. as soon as I upload a pdf, firstImage and file are being set correctly so I dont know what goes wrong anymore.

I’ve Tried:

  • Checked the onChange handler and verified that it gets called.

Questions:

  1. Why is the custom PdfUpload component failing to save the uploaded
    file, while the default file input works?
  2. Is there a specific format or structure required for the onChange
    function to work correctly with Sanity’s file asset system?

Hover Issue with D3 Ribbon Path in Safari

I’m experiencing an issue with D3.js ribbons in Safari where certain SVG path elements don’t respond to hover events for styling changes. The hover effect, such as changing the fill style, works perfectly in Chrome and Firefox. However, in Safari, some paths seem to completely ignore the hover interaction.

I’ve tried all possible pointer-events values (all, auto, visiblePainted, etc.), but it still doesn’t work. Here’s what I’ve already verified:

  • The paths are visible and rendered correctly.
  • There are no overlapping elements obstructing the paths.
  • The hover effects is applied via D3’s .on(“mouseover”, …).

Here’s how I’m implementing the path drawing:

// Dimensions and container setup
const width = 600, height = 600;
const svg = d3.select("#circos-plot")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", `translate(${width / 2},${height / 2})`);

// Updated data with new angles
const data = {
    source: { radius: 200, startAngle: 0.10082134423424959, endAngle: 0.23383773956851167 },
    target: { radius: 200, startAngle: 1.0174690537411528, endAngle: 1.0615254394569593 }
};

// Ribbon generator
const ribbon = d3.ribbon().radius(data.source.radius);

// Append ribbon with hover event
svg.append("path")
    .datum(data)
    .attr("d", ribbon)
    .attr("fill", "steelblue")
    .attr("class", "ribbon")  // Add class for hover styling
    .style("pointer-events", "visibleFill")  // Ensure pointer events work
    .on("mouseover", function(event, d) {
      // Change color on hover
      d3.select(this).transition().duration(300).attr("fill", "orange");
    })
    .on("mouseout", function(event) {
      // Reset color when mouse leaves
      d3.select(this).transition().duration(300).attr("fill", "steelblue");
    });

Below is the complete working example:

https://codepen.io/joko3ono/pen/VYZPwWa

Is there any specific code or adjustments needed to make the SVG behave correctly in Safari, similar to how it works in other browsers?

how to open user default browser from twa application?

I have a Trusted Web Activity (TWA) application, and users can make purchases through it.
The problem is that the payment page should open in the user’s default browser, not inside the TWA app.
However, none of the methods I’ve tried work, and the page still opens inside the TWA app.

i tried below codes:

  • window.open(redirect_url);

  • window.location.href =
    intent://${redirect_url}/#Intent;scheme=https;action=android.intent.action.VIEW;end;`

  • window.location.href =
    intent://${redirect_url}/#Intent;scheme=https;end;`

but none of them work and the page opened inside of my twa app.
also i should mention that i open the website in telegram app and from there my browser got open but when i test on my twa application it not work.
is there a way to solve this issue.

Capacitor and vanilla JS: Load HTML elements in the main HTML

I’m working on a mobile app with capacitor and vanilla Js and I’m following a tutorial to help me set it [up][1]. In the tutorial, it is indicated that to make several pages of our app, we copy and paste the code in each of the pages (index.html, info.html), but I find that a lot of code is duplicated like the header, footer, etc.
Example of index.html:

<!doctype html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="UTF-8" />
    // a lot of header code which we want to import via another source
  </head>
  <body>
    <custom-navbar>
      <h1 slot="title">My capacitor app</h1>
      <div slot="end">
        <a href="/info.html"><button>Info</button></a>
      </div>
    </custom-navbar>
    <script src="./js/navbar.js" type="module"></script>
  </body>
</html>

and I’m looking to load the code that looks similar from a single file a bit like PHP’s include(‘my_file.php’) ($vars) so as not to duplicate the same code in a page.
For example, in my index I would like the header to be loaded from an external file that I can simply import a bit like the class constructor method import in our main html file of a .custom-header.js file which looks like this

`window.customElements.define(
  'custom-header',
  class extends HTMLElement {
    constructor() {
      super();
      SplashScreen.hide();
      const root = this.attachShadow({ mode: 'open' });
      root.innerHTML = `<style>
      :host {
         font-family: -apple-system, BlinkMacSystemFont,....";
         display: block;
         width: 100%;
         height: 100%;
  } etc....` 

And import it in the main html file like this:

<!doctype html>
<html lang="en" dir="ltr">
  <custom-header></custom-header>
  <body>
    <custom-navbar>
      <h1 slot="title">My capacitor app</h1>
      <div slot="end">
        <a href="/info.html"><button>Info</button></a>
      </div>
    </custom-navbar>
    <script src="./js/navbar.js" type="module"></script>
  </body>

What I’ve found so far that works is a javascript import and the document.getelementbyID().innerHTML method as shown here:

const header = `
<head>
    <meta charset="UTF-8" />
    //.. all our header html code
    <meta name="theme-color" content="#31d53d" />
</head>
`
document.getElementById("header").innerHTML = header;

and in our index.html put an id where we want to have the header code:

<!doctype html>
<html lang="en" dir="ltr">
  <div id="header"></div>
  <body>
  <!-- Our specific body code-->
    <script src="./custom-header.js" type="module"></script>   

But i’m not shure if there is no better ways to do this. Thanks
[1]: https://ionic.io/blog/create-powerful-native-mobile-apps-with-capacitor-vanillajs