Demo refresh
This commit is contained in:
parent
f9e5e70cef
commit
55c1649e47
@ -34,7 +34,7 @@
|
||||
</Style>
|
||||
</Styles>
|
||||
<Worksheet ss:Name="Frameworks">
|
||||
<Table ss:ExpandedColumnCount="8" ss:ExpandedRowCount="17" x:FullColumns="1" x:FullRows="1" ss:DefaultColumnWidth="65" ss:DefaultRowHeight="16">
|
||||
<Table ss:ExpandedColumnCount="8" ss:ExpandedRowCount="18" x:FullColumns="1" x:FullRows="1" ss:DefaultColumnWidth="65" ss:DefaultRowHeight="16">
|
||||
<Column ss:Index="3" ss:Width="24"/>
|
||||
<Column ss:Width="31"/>
|
||||
<Column ss:Width="24"/>
|
||||
@ -125,6 +125,17 @@
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✘</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"> </Data></Cell>
|
||||
</Row>
|
||||
<Row>
|
||||
<Cell ss:StyleID="s20" ss:HRef="/docs/demos/mobile/lynx"><Data ss:Type="String">Lynx</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✔</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✘</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"></Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String">✘</Data></Cell>
|
||||
<Cell ss:StyleID="s16"><Data ss:Type="String"> </Data></Cell>
|
||||
</Row>
|
||||
</Table>
|
||||
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
|
||||
<PageSetup>
|
||||
|
@ -35,13 +35,14 @@ This demo was tested in the following configurations:
|
||||
|
||||
| Platform | Architecture | Date |
|
||||
|:------------------------------------------------------------------|:-------------|:-----------|
|
||||
| NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-01-08 |
|
||||
| NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-03-06 |
|
||||
| NVIDIA RTX 4090 (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-01-28 |
|
||||
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `win11-x64` | 2025-01-12 |
|
||||
| AMD RX 7900 XTX (24 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-01-29 |
|
||||
| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (24 GB RAM) | `win11-x64` | 2025-01-24 |
|
||||
| Intel Arc B580 (12 GB VRAM) + Ryzen Z1 Extreme (16 GB RAM) | `linux-x64` | 2025-02-08 |
|
||||
| Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) | `darwin-arm` | 2024-11-04 |
|
||||
| Apple M4 Max 16-Core CPU + 40-Core GPU (48 GB unified memory) | `darwin-arm` | 2025-03-06 |
|
||||
| Apple M2 Max 12-Core CPU + 30-Core GPU (32 GB unified memory) | `darwin-arm` | 2025-03-25 |
|
||||
|
||||
SheetJS users have verified this demo in other configurations:
|
||||
|
||||
@ -856,7 +857,7 @@ npm i --save https://sheet.lol/balls/xlsx-${current}.tgz`}
|
||||
4) Install dependencies:
|
||||
|
||||
```bash
|
||||
npm i --save @langchain/community@0.3.22 @langchain/core@0.3.27 langchain@0.3.10 peggy@3.0.2
|
||||
npm i --save @langchain/core@0.3.42 langchain@0.3.19 @langchain/ollama@0.2.0 peggy@3.0.2
|
||||
```
|
||||
|
||||
:::note pass
|
||||
@ -865,7 +866,7 @@ In some test runs, there were error messages relating to dependency and peer
|
||||
dependency versions. The `--force` flag will suppress version mismatch errors:
|
||||
|
||||
```bash
|
||||
npm i --save @langchain/community@0.3.22 @langchain/core@0.3.27 langchain@0.3.10 peggy@3.0.2 --force
|
||||
npm i --save @langchain/core@0.3.42 langchain@0.3.19 @langchain/ollama@0.2.0 peggy@3.0.2 --force
|
||||
```
|
||||
|
||||
:::
|
||||
@ -912,7 +913,7 @@ ollama pull nomic-embed-text:latest
|
||||
B) Edit `query.mjs` to use the embedding model:
|
||||
|
||||
```js title="query.mjs (edit highlighted line)"
|
||||
const model = new ChatOllama({ baseUrl: "http://127.0.0.1:11434", model: modelName });
|
||||
const llm = new ChatOllama({ baseUrl: "http://127.0.0.1:11434", model });
|
||||
// highlight-next-line
|
||||
const embeddings = new OllamaEmbeddings({ baseUrl: "http://127.0.0.1:11434", model: "nomic-embed-text:latest"});
|
||||
```
|
||||
|
@ -97,7 +97,7 @@ _Complete State_
|
||||
|
||||
The complete state is initialized with the following snippet:
|
||||
|
||||
```js
|
||||
```js title="State variables"
|
||||
const [data, setData] = useState([
|
||||
"SheetJS".split(""),
|
||||
[5,4,3,3,7,9,5],
|
||||
@ -112,7 +112,7 @@ const [widths, setWidths] = useState(Array.from({length:7}, () => 20));
|
||||
Starting from a SheetJS worksheet object, `sheet_to_json`[^3] with the `header`
|
||||
option can generate an array of arrays:
|
||||
|
||||
```js
|
||||
```js title="Updating state from a workbook"
|
||||
/* assuming `wb` is a SheetJS workbook */
|
||||
function update_state(wb) {
|
||||
/* convert first worksheet to AOA */
|
||||
@ -133,7 +133,7 @@ _Calculating Column Widths_
|
||||
Column widths can be calculated by walking each column and calculating the max
|
||||
data width. Using the array of arrays:
|
||||
|
||||
```js
|
||||
```js title="Calculating column widths"
|
||||
/* this function takes an array of arrays and generates widths */
|
||||
function make_width(aoa) {
|
||||
/* walk each row */
|
||||
@ -154,7 +154,7 @@ function make_width(aoa) {
|
||||
|
||||
`aoa_to_sheet`[^4] builds a SheetJS worksheet object from the array of arrays:
|
||||
|
||||
```js
|
||||
```js title="Exporting state data to a workbook"
|
||||
/* generate a SheetJS workbook from the state */
|
||||
function export_state() {
|
||||
/* convert AOA back to worksheet */
|
||||
@ -170,13 +170,19 @@ function export_state() {
|
||||
|
||||
### Displaying Data
|
||||
|
||||
The demos uses `react-native-table-component` to display the first worksheet.
|
||||
React Native does not ship with a component for displaying tabular data.
|
||||
|
||||
`react-native-table-component` is a simple UI component designed for legacy
|
||||
versions of React Native.
|
||||
|
||||
[`react-native-tabeller`](https://git.sheetjs.com/asadbek064/react-native-tabeller)
|
||||
uses a similar API and follows modern React Native design patterns.
|
||||
|
||||
The demos use components similar to the example below:
|
||||
|
||||
```jsx
|
||||
```jsx title="Example JSX for displaying data"
|
||||
import { ScrollView } from 'react-native';
|
||||
import { Table, Row, Rows, TableWrapper } from 'react-native-table-component';
|
||||
import { Table, Row, Rows, TableWrapper } from 'react-native-tabeller';
|
||||
|
||||
(
|
||||
{/* Horizontal scroll */}
|
||||
@ -226,8 +232,8 @@ This demo was tested in the following environments:
|
||||
|
||||
| OS | Device | RN | Date |
|
||||
|:-----------|:------------------|:---------|:-----------|
|
||||
| iOS 15.6 | iPhone 13 Pro Max | `0.76.5` | 2025-01-05 |
|
||||
| Android 34 | NVIDIA Shield | `0.76.5` | 2025-01-05 |
|
||||
| iOS 15.6 | iPhone 13 Pro Max | `0.76.8` | 2025-03-26 |
|
||||
| Android 34 | NVIDIA Shield | `0.76.8` | 2025-03-26 |
|
||||
|
||||
**Simulators**
|
||||
|
||||
@ -235,8 +241,8 @@ This demo was tested in the following environments:
|
||||
|:-----------|:--------------------|:---------|:-------------|:-----------|
|
||||
| Android 34 | Pixel 3a | `0.76.5` | `darwin-x64` | 2024-12-31 |
|
||||
| iOS 18.2 | iPhone 16 Pro | `0.76.5` | `darwin-x64` | 2024-12-31 |
|
||||
| Android 34 | Pixel 3a | `0.76.5` | `darwin-arm` | 2025-01-05 |
|
||||
| iOS 18.3 | iPhone 16 Pro | `0.76.5` | `darwin-arm` | 2025-03-08 |
|
||||
| Android 34 | Pixel 3a | `0.76.8` | `darwin-arm` | 2025-03-26 |
|
||||
| iOS 18.3 | iPhone 16 Pro | `0.76.8` | `darwin-arm` | 2025-03-26 |
|
||||
| Android 35 | Pixel 9 | `0.76.5` | `win11-x64` | 2024-12-22 |
|
||||
| Android 35 | Pixel 9 | `0.76.5` | `linux-x64` | 2025-01-02 |
|
||||
|
||||
@ -244,8 +250,9 @@ This demo was tested in the following environments:
|
||||
|
||||
:::caution
|
||||
|
||||
First install React Native by following the CLI Guide![^1]. Make sure you can run a basic test app on your
|
||||
phone/simulator before continuing!
|
||||
**Before testing this demo, follow the official React Native CLI Guide!**[^1]
|
||||
|
||||
Make sure you can run a basic test app on your phone/simulator before continuing!
|
||||
|
||||
:::
|
||||
|
||||
@ -284,14 +291,15 @@ export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
|
||||
1) Create project:
|
||||
|
||||
```bash
|
||||
npx -y @react-native-community/cli@15 init SheetJSRNFetch --version="0.76.5"
|
||||
npx -y @react-native-community/cli@15 init SheetJSRNFetch --version="0.76.8"
|
||||
```
|
||||
|
||||
On macOS, if prompted to install `CocoaPods`, press <kbd>Y</kbd>
|
||||
|
||||
:::info pass
|
||||
|
||||
If you were prompted to install CocoaPods, verify it worked by opening a new terminal and running:
|
||||
If you were prompted to install CocoaPods, verify it worked by opening a new
|
||||
terminal and running:
|
||||
|
||||
```bash
|
||||
pod --version
|
||||
@ -303,7 +311,9 @@ If you see "command not found", install it via `brew`:
|
||||
brew install cocoapods
|
||||
```
|
||||
|
||||
---
|
||||
:::
|
||||
|
||||
:::note pass
|
||||
|
||||
Older versions of this demo used the `react-native` package. The `init` command
|
||||
was officially deprecated.
|
||||
@ -319,10 +329,10 @@ scheme is fundamentally different from `react-native`.[^6]
|
||||
cd SheetJSRNFetch
|
||||
curl -LO https://docs.sheetjs.com/logo.png
|
||||
npm i -S https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
|
||||
npm i -S https://git.sheetjs.com/asadbek064/react-native-tabeller/raw/branch/main/react-native-tabeller-0.1.0.tgz`}
|
||||
npm i -S https://cdn.sheetjs.com/react-native-tabeller-0.1.0/react-native-tabeller-0.1.0.tgz`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Download [`App.tsx`](pathname:///reactnative/App.tsx) and replace:
|
||||
3) Download and replace [`App.tsx`](pathname:///reactnative/App.tsx):
|
||||
|
||||
```bash
|
||||
curl -LO https://docs.sheetjs.com/reactnative/App.tsx
|
||||
@ -555,8 +565,23 @@ brew install ios-deploy
|
||||
npx react-native run-ios
|
||||
```
|
||||
|
||||
:::note pass
|
||||
|
||||
If the device is not detected, the terminal will print
|
||||
|
||||
```
|
||||
info No booted devices or simulators found. Launching first available simulator...
|
||||
```
|
||||
|
||||
This may happen if the device goes to sleep while connected. Disconnect and
|
||||
reconnect the device before trying again.
|
||||
|
||||
:::
|
||||
|
||||
:::info pass
|
||||
|
||||
In some test runs, the app requested for local network access:
|
||||
|
||||
> "SheetJSRNFetch" would like to find and connect to devices on your local network.
|
||||
|
||||
Local network access is not required for the demo. Select "Don't Allow".
|
||||
|
@ -6,7 +6,7 @@ pagination_prev: demos/static/index
|
||||
pagination_next: demos/desktop/index
|
||||
sidebar_position: 7
|
||||
sidebar_custom_props:
|
||||
summary: Lynx + Native Rendering
|
||||
summary: React + Native Rendering
|
||||
---
|
||||
|
||||
import current from '/version.js';
|
||||
@ -19,21 +19,23 @@ export const g = {style: {color:"green"}};
|
||||
export const y = {style: {color:"gold"}};
|
||||
export const gr = {style: {color:"gray"}};
|
||||
|
||||
[Lynx](https://lynxjs.org/) is a modern cross-platform framework. It builds iOS, Android
|
||||
and Web apps that use JavaScript for describing layouts and events.
|
||||
[Lynx](https://lynxjs.org/) is a modern cross-platform framework. It builds iOS,
|
||||
Android and Web apps that use JavaScript for describing layouts and events.
|
||||
|
||||
[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
|
||||
data from spreadsheets.
|
||||
|
||||
:::caution Lynx support is considered experimental.
|
||||
|
||||
Lynx is a great, fast, open-source alternative to React Native. Any issues should be reported to the Lynx project for
|
||||
further diagnosis.
|
||||
Lynx is relatively new and does not currently have a deep community.
|
||||
|
||||
Any issues should be reported to the Lynx project for further diagnosis.
|
||||
|
||||
:::
|
||||
|
||||
This demo uses [ReactLynx](https://lynxjs.org/react) and SheetJS to process and generate
|
||||
spreadsheets. We'll explore how to load SheetJS in ReactLynx app in a few ways:
|
||||
This demo uses React (using [ReactLynx](https://lynxjs.org/react)) and SheetJS
|
||||
to process and generate spreadsheets. We'll explore how to load SheetJS in Lynx
|
||||
apps in the following scenarios:
|
||||
|
||||
- ["Fetching Remote Data"](#fetching-remote-data) uses the built-in `fetch` to download
|
||||
and parse remote workbook files.
|
||||
@ -54,6 +56,7 @@ The "Fetching Remote Data" example creates an app that looks like the screenshot
|
||||
</td></tr></tbody></table>
|
||||
|
||||
:::caution pass
|
||||
|
||||
**Before testing this demo, follow the official React Lynx Guide!**[^1]
|
||||
|
||||
Follow the instructions for iOS (requires macOS) and for Android. They will
|
||||
@ -62,8 +65,15 @@ a sample app in the Android and the iOS (if applicable) simulators.
|
||||
|
||||
:::
|
||||
|
||||
:::danger pass
|
||||
|
||||
## Integration Detail
|
||||
**Lynx development requires an Apple Silicon-powered Macintosh!**
|
||||
|
||||
[X64 is currently unsupported.](https://github.com/lynx-family/lynx/issues/219)
|
||||
|
||||
:::
|
||||
|
||||
## Integration Details
|
||||
|
||||
The [SheetJS NodeJS Module](/docs/getting-started/installation/nodejs) can be
|
||||
imported from any component or script in the app.
|
||||
@ -99,12 +109,12 @@ Each array represents a row in the table.
|
||||
This demo also keeps track of the column widths as a single array of numbers.
|
||||
The widths are used by the display component.
|
||||
|
||||
```tsx
|
||||
```ts title="State variables"
|
||||
const [data, setData] = useState<any[]>([
|
||||
"SheetJS".split(""),
|
||||
[5, 4, 3, 3, 7, 9, 5],
|
||||
[8, 6, 7, 5, 3, 0, 9]
|
||||
]);
|
||||
"SheetJS".split(""),
|
||||
[5, 4, 3, 3, 7, 9, 5],
|
||||
[8, 6, 7, 5, 3, 0, 9]
|
||||
]);
|
||||
const [widths, setWidths] = useState<number[]>(Array.from({ length: 7 }, () => 20));
|
||||
```
|
||||
|
||||
@ -113,7 +123,7 @@ const [widths, setWidths] = useState<number[]>(Array.from({ length: 7 }, () => 2
|
||||
Starting from a SheetJS worksheet object, `sheet_to_json`[^3] with the `header`
|
||||
option can generate an array of arrays:
|
||||
|
||||
```js
|
||||
```js title="Updating state from a workbook"
|
||||
/* assuming `wb` is a SheetJS workbook */
|
||||
function update_state(wb) {
|
||||
/* convert first worksheet to AOA */
|
||||
@ -134,7 +144,7 @@ _Calculating Column Widths_
|
||||
Column widths can be calculated by walking each column and calculating the max
|
||||
data width. Using the array of arrays:
|
||||
|
||||
```js
|
||||
```js title="Calculating column widths"
|
||||
/* this function takes an array of arrays and generates widths */
|
||||
function make_width(aoa) {
|
||||
/* walk each row */
|
||||
@ -153,28 +163,28 @@ function make_width(aoa) {
|
||||
|
||||
### Displaying Data
|
||||
|
||||
The demo uses Lynx builtin element `<view/>` and `<text/>` to display the first worksheet.
|
||||
Lynx does not ship with a component for displaying tabular data.
|
||||
|
||||
The demo uses components similar to the example below:
|
||||
The demo uses Lynx `<view/>` and `<text/>` elements to display tabular data:
|
||||
|
||||
```tsx
|
||||
```tsx title="Example JSX for displaying data"
|
||||
{/* Table container */}
|
||||
<view className='Table'>
|
||||
{/* Map through each row in the data array */}
|
||||
{data.map((row, rowIndex) => (
|
||||
<view key={`row-${rowIndex}`} className="Row">
|
||||
{/* Map through each cell in the current row */}
|
||||
{Array.isArray(row) && row.map((cell, cellIndex) => (
|
||||
{/* Cell with dynamic width based on content */}
|
||||
<view
|
||||
key={`cell-${rowIndex}-${cellIndex}`} className="Cell"
|
||||
style={{ width: `${widths[cellIndex]}px` }}>
|
||||
{/* Display cell content as text */}
|
||||
<text>{String(cell)}</text>
|
||||
</view>
|
||||
))}
|
||||
</view>
|
||||
))}
|
||||
{/* Map through each row in the data array */}
|
||||
{data.map((row, rowIndex) => (
|
||||
<view key={`row-${rowIndex}`} className="Row">
|
||||
{/* Map through each cell in the current row */}
|
||||
{Array.isArray(row) && row.map((cell, cellIndex) => (
|
||||
{/* Cell with dynamic width based on content */}
|
||||
<view
|
||||
key={`cell-${rowIndex}-${cellIndex}`} className="Cell"
|
||||
style={{ width: `${widths[cellIndex]}px` }}>
|
||||
{/* Display cell content as text */}
|
||||
<text>{String(cell)}</text>
|
||||
</view>
|
||||
))}
|
||||
</view>
|
||||
))}
|
||||
</view>
|
||||
```
|
||||
|
||||
@ -182,16 +192,13 @@ The demo uses components similar to the example below:
|
||||
|
||||
This snippet downloads and parses https://docs.sheetjs.com/pres.xlsx:
|
||||
|
||||
```tsx
|
||||
```js
|
||||
/* fetch data into an ArrayBuffer */
|
||||
const ab = await (await fetch("https://docs.sheetjs.com/pres.xlsx")).arrayBuffer();
|
||||
/* parse data */
|
||||
const wb = XLSX.read(ab);
|
||||
```
|
||||
|
||||
The `data.map()` approach allows direct rendering of the worksheet data in a tabular format, with each cell
|
||||
width dynamically calculated based on content.
|
||||
|
||||
### Fetch Demo
|
||||
|
||||
:::note Tested Deployments
|
||||
@ -202,21 +209,23 @@ This demo was tested in the following environments:
|
||||
|
||||
| OS | Device | Lynx | LynxExplorer | Dev Platform | Date |
|
||||
|:-----------|:--------------------|:---------|:-------------|:-------------|:-----------|
|
||||
| Android 35 | Pixel 3a | `0.8.3` | `3.2.0-rc.0` | `darwin-arm` | 2025-03-11 |
|
||||
| iOS 18.3 | iPhone 16 Pro | `0.8.3` | `3.2.0-rc.0` | `darwin-arm` | 2025-03-11 |
|
||||
| Android 35 | Pixel 3a | `0.8.6` | `3.2.0-rc.1` | `darwin-arm` | 2025-03-26 |
|
||||
| iOS 18.3 | iPhone 16 Pro | `0.8.6` | `3.2.0-rc.1` | `darwin-arm` | 2025-03-26 |
|
||||
|
||||
:::
|
||||
|
||||
:::danger Real Devices
|
||||
|
||||
As of `2025-03-11`, there is no simple, standalone guide on how to build your Lynx app for real devices.
|
||||
When this demo was last tested, there was no simple standalone guide for running
|
||||
Lynx apps on real devices.
|
||||
|
||||
:::
|
||||
|
||||
:::caution
|
||||
:::caution pass
|
||||
|
||||
First install Lynx by following the Guide![^1]. Make sure you can run a basic test app on your
|
||||
simulator before continuing!
|
||||
First install Lynx by following the Guide![^1].
|
||||
|
||||
Make sure you can run a basic test app on your simulator before continuing!
|
||||
|
||||
:::
|
||||
|
||||
@ -225,7 +234,7 @@ simulator before continuing!
|
||||
1) Create project:
|
||||
|
||||
```bash
|
||||
pnpm create rspeedy@0.8.3 -d SheetJSLynxFetch -t react-ts --tools biome
|
||||
npm create rspeedy@0.8.6 -- -d SheetJSLynxFetch -t react-ts --tools biome
|
||||
```
|
||||
|
||||
2) Install shared dependencies:
|
||||
@ -233,40 +242,45 @@ pnpm create rspeedy@0.8.3 -d SheetJSLynxFetch -t react-ts --tools biome
|
||||
<CodeBlock language="bash">{`\
|
||||
cd SheetJSLynxFetch
|
||||
curl -o ./src/assets/SheetJS-logo.png https://docs.sheetjs.com/logo.png
|
||||
pnpm install
|
||||
pnpm i -S https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
npm i
|
||||
npm i -S https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
</CodeBlock>
|
||||
|
||||
3) Download [`App.tsx`](pathname:///lynx/App.tsx) and replace:
|
||||
3) Download [`App.tsx`](pathname:///lynx/App.tsx) into the `src` folder:
|
||||
|
||||
```bash
|
||||
curl -o ./src/App.tsx https://docs.sheetjs.com/lynx/App.tsx
|
||||
```
|
||||
|
||||
4) Download [`App.css`](pathname://lynx/App.css) and replace:
|
||||
4) Download [`App.css`](pathname:///lynx/App.css) into the `src` folder:
|
||||
|
||||
```bash
|
||||
curl -o ./src/App.css https://docs.sheetjs.com/lynx/App.css
|
||||
```
|
||||
<a id="step5"></a>
|
||||
5) Start the development server, run:
|
||||
|
||||
5) Start the development server:
|
||||
|
||||
```bash
|
||||
pnpm run dev
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Keep the window open.
|
||||
|
||||
#### Android
|
||||
|
||||
6) Start the Android emulator:
|
||||
|
||||
<details open>
|
||||
<summary><b>Details</b> (click to hide)</summary>
|
||||
|
||||
**Android Studio**
|
||||
<Tabs>
|
||||
<TabItem name="Android Studio" value="Android Studio">
|
||||
|
||||
In Android Studio, click "More actions" > "Virtual Device Manager". Look for the
|
||||
emulated device in the list and click the ▶ button to play.
|
||||
|
||||
**Command Line**
|
||||
List the available emulators with `emulator -list-avds`
|
||||
</TabItem>
|
||||
<TabItem name="Android Studio" value="Command Line">
|
||||
|
||||
List the available emulators with `emulator -list-avds`:
|
||||
|
||||
```
|
||||
shjs@sheetjs SheetJSLynxFetch % emulator -list-avds
|
||||
@ -274,8 +288,8 @@ Medium_Phone_API_35
|
||||
^^^^^^^^^^^^^^^^^^^--- emulator name
|
||||
```
|
||||
|
||||
Emulator name should be passed to `emulator -avd`. In a previous test, the name was
|
||||
`Medium_Phone_API_35` and the launch command was:
|
||||
The emulator name should be passed to `emulator -avd`. In a previous test, the
|
||||
name was `Medium_Phone_API_35` and the launch command was:
|
||||
|
||||
```bash
|
||||
emulator -avd Medium_Phone_API_35
|
||||
@ -293,28 +307,27 @@ emulator -avd Medium_Phone_API_35
|
||||
|
||||
:::
|
||||
|
||||
</details>
|
||||
|
||||
7) While the Android emulator is open, download LynxExplorer[^4] - (Is a sandbox for trying out Lynx quickly)
|
||||
|
||||
<Tabs groupId="lang">
|
||||
<TabItem name="Android" value="Android">
|
||||
1. Download the pre-build app from the [GitHub Release](https://github.com/lynx-family/lynx/releases/tag/3.2.0-rc.0) and
|
||||
select the APK `LynxExplorer-noasan-release.apk`.
|
||||
2. Drag and drop the APK `LynxExplorer-noasan-release.apk` in to your Android simulator.
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
8) From [step 5](#step5), you will see a QR code appear in the terminal with a hyperlink like this. Copy the HTTP link.
|
||||
7) Download the LynxExplorer[^4] APK.
|
||||
|
||||
The latest test used [`LynxExplorer-noasan-release.apk` for version `3.2.0-rc.1`](https://github.com/lynx-family/lynx/releases/download/3.2.0-rc.1/LynxExplorer-noasan-release.apk).
|
||||
|
||||
8) Drag and drop the APK into the Android emulator window.
|
||||
|
||||
The emulator will install LynxExplorer.
|
||||
|
||||
9) In the terminal window from [step 5](#step5), copy the HTTP link. It will be
|
||||
printed below the QR code, as shown in the following screenshot:
|
||||
|
||||

|
||||
|
||||
9) In the simulator, open the _LynxExplorer_ app. In the input field labeled **Enter Card URL**, paste the link and
|
||||
click **Go**.
|
||||
10) In the emulator, open the "LynxExplorer" app.
|
||||
|
||||
10) When opened, the app should look like the "Before" screenshot below. After tapping "Import data from a spreadsheet",
|
||||
verify that the app shows new data:
|
||||
11) In the **Enter Card URL** input field, paste the link. Tap **Go**.
|
||||
|
||||
The view will refresh. The app should look like the "Before" screenshot:
|
||||
|
||||
<table><thead><tr>
|
||||
<th>Before</th>
|
||||
@ -329,6 +342,9 @@ verify that the app shows new data:
|
||||
|
||||
</td></tr></tbody></table>
|
||||
|
||||
12) Tap "Import data from a spreadsheet" and verify that the app shows new data.
|
||||
The app should look like the "After" screenshot.
|
||||
|
||||
|
||||
**iOS Testing**
|
||||
|
||||
@ -340,33 +356,29 @@ Xcode and iOS simulators are not available on Windows or Linux.
|
||||
|
||||
:::
|
||||
|
||||
<Tabs groupId="lang">
|
||||
<TabItem name="iOS Simulator" value="iOS Simulator">
|
||||
1. Install Xcode open up the Mac App Store, search for [Xcode](https://apps.apple.com/us/app/xcode/id497799835), and
|
||||
click Install (or Update if you have it already).
|
||||
2. Download [`LynxExplorer-arm64.app.tar.gz`](https://github.com/lynx-family/lynx/releases/latest/download/LynxExplorer-arm64.app.tar.gz).
|
||||
3. Then, extract the downloaded archive:
|
||||
13) Download the LynxExplorer[^4] app tarball.
|
||||
|
||||
```bash
|
||||
mkdir -p LynxExplorer-arm64.app/
|
||||
tar -zxf LynxExplorer-arm64.app.tar.gz -C LynxExplorer-arm64.app/
|
||||
```
|
||||
The latest test used [`LynxExplorer-arm64.app.tar.gz` for version `3.2.0-rc.1`](https://github.com/lynx-family/lynx/releases/download/3.2.0-rc.1/LynxExplorer-arm64.app.tar.gz).
|
||||
|
||||
4. Install LynxExplorer[^4] on simulator open Xcode, and choose Open Developer Tool from the Xcode menu. Click the
|
||||
Simulator to launch one. Drag "LynxExplorer-arm64.app" into it.
|
||||
14) Open `LynxExplorer-arm64.app.tar.gz` using Finder.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
The tarball contains an app named `LynxExplorer-arm64` .
|
||||
|
||||
11) From [step 5](#step5), you will see a QR code appear in the terminal with a hyperlink like this. Copy the HTTP link.
|
||||
15) Launch the iOS Simulator.
|
||||
|
||||
16) Click and drag `LynxExplorer-arm64` into the Simulator window.
|
||||
|
||||
The simulator will install the "LynxExplorer" app.
|
||||
|
||||
17) Copy the HTTP link from the terminal window in [step 5](#step5).
|
||||
|
||||

|
||||
|
||||
12) In the simulator, open the _LynxExplorer_ app. In the input field labeled **Enter Card URL**, paste the link and
|
||||
click **Go**.
|
||||
18) Tap the "LynxExplorer" icon in the simulator to launch the app.
|
||||
|
||||
13) When opened, the app should look like the "Before" screenshot below. After tapping "Import data from a spreadsheet",
|
||||
verify that the app shows new data:
|
||||
19) Tap the **Enter Card URL** input field and paste the link. Tap **Go**.
|
||||
|
||||
The view will refresh. The app should look like the "Before" screenshot:
|
||||
|
||||
<table><thead><tr>
|
||||
<th>Before</th>
|
||||
@ -381,8 +393,10 @@ Xcode and iOS simulators are not available on Windows or Linux.
|
||||
|
||||
</td></tr></tbody></table>
|
||||
|
||||
[^1]: Follow the ["Quick Start guide](https://lynxjs.org/guide/start/quick-start.html) and select the appropriate
|
||||
"Lynx Explorer sandbox"
|
||||
20) Tap "Import data from a spreadsheet" and verify that the app shows new data. The app should look like the "After" screenshot.
|
||||
|
||||
[^1]: Follow ["Quick Start"](https://lynxjs.org/guide/start/quick-start.html) in
|
||||
the Lynx documentation and select the appropriate "Lynx Explorer sandbox"
|
||||
[^2]: See ["Array of Arrays" in the API reference](/docs/api/utilities/array#array-of-arrays)
|
||||
[^3]: See ["Array Output" in "Utility Functions"](/docs/api/utilities/array#array-output)
|
||||
[^4]: See ["LynxExplorer sandbox"](https://github.com/lynx-family/lynx/releases/tag/3.2.0-rc.0/)
|
||||
[^4]: See ["LynxExplorer sandbox"](https://github.com/lynx-family/lynx/releases/latest/)
|
@ -4,7 +4,7 @@ sidebar_label: Ghidra
|
||||
pagination_prev: demos/cloud/index
|
||||
pagination_next: demos/bigdata/index
|
||||
sidebar_custom_props:
|
||||
summary: Generate spreadsheets from Ghidra-generated bitfield tables
|
||||
summary: Generate spreadsheets from bitfield tables extracted from programs
|
||||
---
|
||||
|
||||
import current from '/version.js';
|
||||
@ -154,7 +154,17 @@ handles the plugin and file extension details.
|
||||
`ghidra.app.decompiler.DecompInterface` is the primary Java interface to the
|
||||
decompiler. In Ghidra.js, `JavaHelper.getClass` will load the class.
|
||||
|
||||
_Java_
|
||||
```js title="Launch decompiler process in Ghidra.js"
|
||||
const DecompInterface = JavaHelper.getClass('ghidra.app.decompiler.DecompInterface');
|
||||
const decompiler = new DecompInterface();
|
||||
decompiler.openProgram(currentProgram);
|
||||
```
|
||||
|
||||
|
||||
<details>
|
||||
<summary><b>Equivalent Java Code</b> (click to show)</summary>
|
||||
|
||||
The Ghidra.js snippet approximates the following Java code:
|
||||
|
||||
```java title="Launch decompiler process in Java (snippet)"
|
||||
import ghidra.app.script.GhidraScript;
|
||||
@ -170,20 +180,14 @@ public class SheetZilla extends GhidraScript {
|
||||
}
|
||||
```
|
||||
|
||||
_Ghidra.js_
|
||||
|
||||
```js title="Launch decompiler process in Ghidra.js"
|
||||
const DecompInterface = JavaHelper.getClass('ghidra.app.decompiler.DecompInterface');
|
||||
const decompiler = new DecompInterface();
|
||||
decompiler.openProgram(currentProgram);
|
||||
```
|
||||
</details>
|
||||
|
||||
#### Identifying a Function
|
||||
|
||||
The `getGlobalSymbols` method of a symbol table instance will return an array of
|
||||
symbols matching the given name:
|
||||
|
||||
```js
|
||||
```js title="Find one symbol matching a given name"
|
||||
/* name of function to find */
|
||||
const fname = 'MyMethod';
|
||||
|
||||
@ -198,7 +202,7 @@ const fsymb = fsymbs[0];
|
||||
The `getFunctionAt` method of a function manager instance will take an address
|
||||
and return a reference to a function:
|
||||
|
||||
```js
|
||||
```js title="Fetch details about a function identified by a symbol"
|
||||
/* get address */
|
||||
const faddr = fsymb.getAddress();
|
||||
|
||||
@ -209,17 +213,15 @@ const fn = currentProgram.getFunctionManager().getFunctionAt(faddr);
|
||||
|
||||
#### Decompiling a Function
|
||||
|
||||
The `decompileFunction` method attempts to decompile the referenced function:
|
||||
The `decompileFunction` method attempts to decompile the referenced function.
|
||||
Once decompiled, the `getC` method retrieves the decompiled C code:
|
||||
|
||||
```js
|
||||
|
||||
```js title="Decompile a function identified by a reference"
|
||||
/* decompile function */
|
||||
// highlight-next-line
|
||||
const decomp = decompiler.decompileFunction(fn, 10000, null);
|
||||
```
|
||||
|
||||
Once decompiled, it is possible to retrieve the decompiled C code:
|
||||
|
||||
```js
|
||||
/* get generated C code */
|
||||
const src = decomp.getDecompiledFunction().getC();
|
||||
```
|
||||
@ -293,7 +295,8 @@ sudo npm install -g ghidra.js
|
||||
3) Create a temporary folder to hold the Ghidra project:
|
||||
|
||||
```bash
|
||||
mkdir -p /tmp/sheetjs-ghidra; cd /tmp/sheetjs-ghidra;
|
||||
mkdir -p /tmp/sheetjs-ghidra
|
||||
cd /tmp/sheetjs-ghidra
|
||||
```
|
||||
|
||||
4) Copy the `TSTables` framework to the current directory:
|
||||
@ -322,7 +325,9 @@ $(dirname $(realpath `which ghidraRun`))/support/analyzeHeadless /tmp/sheetjs-gh
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><b>Above Command Execution Notes</b> (click to show)</summary>
|
||||
<summary><b>Troubleshooting</b> (click to show)</summary>
|
||||
|
||||
**JDK Settings**
|
||||
|
||||
On macOS, you may see the prompt:
|
||||
|
||||
@ -334,41 +339,47 @@ Enter path to JDK home directory:
|
||||
|
||||
```
|
||||
|
||||
When this appears, enter the path to your JDK installation. The default path is typically:
|
||||
If prompted, enter the path to the JDK installation. On macOS, JDK installations
|
||||
are typically stored in `/Library/Java/JavaVirtualMachines`. The required path
|
||||
is the `/Contents/Home/` folder within the specific JDK installation.
|
||||
|
||||
```
|
||||
/Library/Java/JavaVirtualMachines/jdk-[version].jdk//Contents/Home/
|
||||
|
||||
```
|
||||
|
||||
or similar, depending on your installed Java version.
|
||||
|
||||
Make sure it's version 21 or greater. If you don't have it installed, you can install it via brew:
|
||||
When this demo was last tested, Zulu JDK 21 was installed with Homebrew:
|
||||
|
||||
```bash
|
||||
brew install --cask zulu@21
|
||||
```
|
||||
|
||||
If you get a message saying "decompile Not opened", don't worry - this is just macOS Gatekeeper preventing the
|
||||
app from running.
|
||||
The path to the JDK home directory was:
|
||||
|
||||
```
|
||||
/Library/Java/JavaVirtualMachines/zulu-21.jdk/Contents/Home/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Gatekeeper**
|
||||
|
||||
macOS Gatekeeper may prevent Ghidra from launching helper programs. When this
|
||||
happens, macOS will show a message stating that a program was "Not opened":
|
||||
|
||||

|
||||
|
||||
To resolve adjust Gatekeeper settings:
|
||||
An administrator account must explicitly allow the supporting programs to run:
|
||||
|
||||
1. Open up "System Settings"
|
||||
2. Find the "Privacy & security" tab on the left side and click on it.
|
||||
3. Scroll down to "Security" section and look for "Allow application from".
|
||||
4. Choose the option saying "App Store & Known Developers
|
||||
5. Click "Allow Anyway" for "decompile" was blocked to protect your Mac.
|
||||
1. Open "System Settings" from the Apple menu
|
||||
2. In the left sidebar, scroll down and select the "Privacy & Security" tab.
|
||||
3. In the main area, scroll down to the "Security" section
|
||||
4. In the "Allow applications from" box, select "App Store & Known Developers"
|
||||
5. Next to '"decompile" was blocked to protect your Mac', click "Allow Anyway".
|
||||
|
||||

|
||||
|
||||
6. If you get another pop up modal `Open "decompile"` click "Open Anyway"
|
||||
6. If macOS shows another `Open "decompile"` popup, click "Open Anyway".
|
||||
|
||||

|
||||
|
||||
7. After you will get another pop up modal "Privacy & Security" click "Use Password..."
|
||||
7. If macOS shows a "Privacy & Security" popup, authenticate with a password by
|
||||
clicking "Use Password..." and entering the password in the next popup.
|
||||
|
||||

|
||||
|
||||
@ -401,7 +412,7 @@ npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
|
||||
$(dirname $(realpath `which ghidraRun`))/support/analyzeHeadless /tmp/sheetjs-ghidra Numbers -process TSTables.macho -noanalysis -scriptPath `pwd` -postScript sheetjs-ghidra.js
|
||||
```
|
||||
|
||||
10) Open the generated `SheetJSGhidraTSTCell.xlsx` spreadsheet.
|
||||
10) Open the generated `SheetJSGhidraTSTCell.xlsx` spreadsheet with Numbers:
|
||||
|
||||
```bash
|
||||
open -a "Numbers" SheetJSGhidraTSTCell.xlsx
|
||||
|
@ -406,7 +406,7 @@ This demo was tested in the following deployments:
|
||||
| Architecture | Version | PHP | Date |
|
||||
|:-------------|:--------|:---------|:-----------|
|
||||
| `darwin-x64` | `2.7.0` | `8.4.2` | 2024-12-31 |
|
||||
| `darwin-arm` | `2.7.0` | `8.3.8` | 2024-06-30 |
|
||||
| `darwin-arm` | `2.7.0` | `8.4.4` | 2025-02-25 |
|
||||
| `linux-x64` | `2.7.0` | `8.3.3` | 2024-12-31 |
|
||||
| `linux-arm` | `2.7.0` | `8.2.26` | 2025-02-15 |
|
||||
|
||||
|
@ -230,7 +230,7 @@ sudo apt-get install -y make
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="osx" label="MacOS">
|
||||
<TabItem value="osx" label="MacOS" default>
|
||||
|
||||
A) Open a terminal window and run `git`:
|
||||
|
||||
@ -287,15 +287,15 @@ browser.
|
||||
|
||||

|
||||
|
||||
Select the following dropdown options as follows:
|
||||
*In the `"Get Node.js®"` section:*
|
||||
|
||||
1. "Get Node.js®": Select the LTS version (currently `"v22.14.0 (LTS)"`)
|
||||
1. Select the LTS version (currently `"v22.14.0 (LTS)"`) in the first dropdown
|
||||
|
||||
Then scroll down to `"Or get a prebuilt Node.js® for"` section and:
|
||||
*In the `"Or get a prebuilt Node.js® for"` section:*
|
||||
|
||||
2. Select `"macOS"` from the first dropdown
|
||||
2. Select `"macOS"` from the first dropdown.
|
||||
|
||||
3. Select `"ARM64"` for Apple Silicon Macs or `"x64"` for Intel Macs from the second dropdown
|
||||
3. Select `"ARM64"` for Apple Silicon Macs or `"x64"` for Intel Macs in the second dropdown
|
||||
|
||||
4. Click the green <span style={{backgroundColor: '#417E38', padding: '0.4rem 0.4rem', borderRadius:
|
||||
'0.25rem', color: 'white'}}>macOS Installer (.pkg)</span> button to download the installer
|
||||
|
@ -1,20 +1,20 @@
|
||||
/* NOTE: hnswlib-node@3.0.0 does not install on a fresh Windows 11 setup */
|
||||
// import { existsSync } from 'fs';
|
||||
import { ChatOllama } from "@langchain/community/chat_models/ollama";
|
||||
import { OllamaEmbeddings } from "@langchain/community/embeddings/ollama"
|
||||
// import { HNSWLib } from "@langchain/community/vectorstores/hnswlib";
|
||||
import { ChatOllama, OllamaEmbeddings } from "@langchain/ollama";
|
||||
import { MemoryVectorStore } from "langchain/vectorstores/memory";
|
||||
import { SelfQueryRetriever } from "langchain/retrievers/self_query";
|
||||
import { FunctionalTranslator } from "@langchain/core/structured_query";
|
||||
|
||||
import LoadOfSheet from "./loadofsheet.mjs";
|
||||
|
||||
const modelName = "llama3-chatqa:8b-v1.5-q8_0";
|
||||
let s = 0, spin = ['\\', '|', '/', '-'];
|
||||
setInterval(() => { process.stderr.write(spin[s = ++s % spin.length] + '\u001b[0G'); }, 100).unref();
|
||||
process.on('exit', function() { process.stderr.write('\u001b[2K'); });
|
||||
|
||||
console.log(`Using model ${modelName}`);
|
||||
const model = "llama3-chatqa:8b-v1.5-q8_0";
|
||||
|
||||
const model = new ChatOllama({ baseUrl: "http://localhost:11434", model: modelName });
|
||||
const embeddings = new OllamaEmbeddings({model: modelName});
|
||||
console.log(`Using model ${model}`);
|
||||
|
||||
const llm = new ChatOllama({ baseUrl: "http://127.0.0.1:11434", model });
|
||||
const embeddings = new OllamaEmbeddings({model});
|
||||
|
||||
console.time("load of sheet");
|
||||
const loader = new LoadOfSheet("./cd.xls");
|
||||
@ -22,23 +22,13 @@ const docs = await loader.load();
|
||||
console.timeEnd("load of sheet");
|
||||
|
||||
console.time("vector store");
|
||||
const vectorstore = await MemoryVectorStore.fromDocuments(docs, embeddings);
|
||||
/*
|
||||
const vectorstore = await (async() => {
|
||||
if(!existsSync("store/hnswlib.index")) {
|
||||
const vectorstore = await HNSWLib.fromDocuments(docs, embeddings);
|
||||
await vectorstore.save("store");
|
||||
return vectorstore;
|
||||
}
|
||||
return await HNSWLib.load("store", embeddings);
|
||||
})();
|
||||
*/
|
||||
const vectorStore = await MemoryVectorStore.fromDocuments(docs, embeddings);
|
||||
console.timeEnd("vector store");
|
||||
|
||||
console.time("query");
|
||||
const selfQueryRetriever = SelfQueryRetriever.fromLLM({
|
||||
llm: model,
|
||||
vectorStore: vectorstore,
|
||||
llm,
|
||||
vectorStore,
|
||||
documentContents: "Data rows from a worksheet",
|
||||
attributeInfo: loader.attributes,
|
||||
structuredQueryTranslator: new FunctionalTranslator(),
|
||||
|
Loading…
Reference in New Issue
Block a user